132001f49Smrg 232001f49Smrg/* Copyright (c) Mark J. Kilgard, 1994. */ 332001f49Smrg 432001f49Smrg/* 532001f49Smrg * (c) Copyright 1993, Silicon Graphics, Inc. 632001f49Smrg * ALL RIGHTS RESERVED 732001f49Smrg * Permission to use, copy, modify, and distribute this software for 832001f49Smrg * any purpose and without fee is hereby granted, provided that the above 932001f49Smrg * copyright notice appear in all copies and that both the copyright notice 1032001f49Smrg * and this permission notice appear in supporting documentation, and that 1132001f49Smrg * the name of Silicon Graphics, Inc. not be used in advertising 1232001f49Smrg * or publicity pertaining to distribution of the software without specific, 1332001f49Smrg * written prior permission. 1432001f49Smrg * 1532001f49Smrg * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" 1632001f49Smrg * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, 1732001f49Smrg * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR 1832001f49Smrg * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON 1932001f49Smrg * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, 2032001f49Smrg * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY 2132001f49Smrg * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, 2232001f49Smrg * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF 2332001f49Smrg * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN 2432001f49Smrg * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON 2532001f49Smrg * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE 2632001f49Smrg * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. 2732001f49Smrg * 2832001f49Smrg * US Government Users Restricted Rights 2932001f49Smrg * Use, duplication, or disclosure by the Government is subject to 3032001f49Smrg * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph 3132001f49Smrg * (c)(1)(ii) of the Rights in Technical Data and Computer Software 3232001f49Smrg * clause at DFARS 252.227-7013 and/or in similar or successor 3332001f49Smrg * clauses in the FAR or the DOD or NASA FAR Supplement. 3432001f49Smrg * Unpublished-- rights reserved under the copyright laws of the 3532001f49Smrg * United States. Contractor/manufacturer is Silicon Graphics, 3632001f49Smrg * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. 3732001f49Smrg * 3832001f49Smrg * OpenGL(TM) is a trademark of Silicon Graphics, Inc. 3932001f49Smrg */ 4032001f49Smrg/* 4132001f49Smrg * dof.c 4232001f49Smrg * This program demonstrates use of the accumulation buffer to 4332001f49Smrg * create an out-of-focus depth-of-field effect. The teapots 4432001f49Smrg * are drawn several times into the accumulation buffer. The 4532001f49Smrg * viewing volume is jittered, except at the focal point, where 4632001f49Smrg * the viewing volume is at the same position, each time. In 4732001f49Smrg * this case, the gold teapot remains in focus. 4832001f49Smrg */ 4932001f49Smrg#include <stdlib.h> 5032001f49Smrg#include <math.h> 5132001f49Smrg#include "glut_wrap.h" 5232001f49Smrg#include "jitter.h" 5332001f49Smrg 5432001f49Smrg#define PI_ 3.14159265358979323846 5532001f49Smrg 5632001f49Smrg/* accFrustum() 5732001f49Smrg * The first 6 arguments are identical to the glFrustum() call. 5832001f49Smrg * 5932001f49Smrg * pixdx and pixdy are anti-alias jitter in pixels. 6032001f49Smrg * Set both equal to 0.0 for no anti-alias jitter. 6132001f49Smrg * eyedx and eyedy are depth-of field jitter in pixels. 6232001f49Smrg * Set both equal to 0.0 for no depth of field effects. 6332001f49Smrg * 6432001f49Smrg * focus is distance from eye to plane in focus. 6532001f49Smrg * focus must be greater than, but not equal to 0.0. 6632001f49Smrg * 6732001f49Smrg * Note that accFrustum() calls glTranslatef(). You will 6832001f49Smrg * probably want to insure that your ModelView matrix has been 6932001f49Smrg * initialized to identity before calling accFrustum(). 7032001f49Smrg */ 7132001f49Smrgstatic void accFrustum(GLdouble left, GLdouble right, GLdouble bottom, 7232001f49Smrg GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx, 7332001f49Smrg GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus) 7432001f49Smrg{ 7532001f49Smrg GLdouble xwsize, ywsize; 7632001f49Smrg GLdouble dx, dy; 7732001f49Smrg GLint viewport[4]; 7832001f49Smrg 7932001f49Smrg glGetIntegerv (GL_VIEWPORT, viewport); 8032001f49Smrg 8132001f49Smrg xwsize = right - left; 8232001f49Smrg ywsize = top - bottom; 8332001f49Smrg 8432001f49Smrg dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*nnear/focus); 8532001f49Smrg dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*nnear/focus); 8632001f49Smrg 8732001f49Smrg glMatrixMode(GL_PROJECTION); 8832001f49Smrg glLoadIdentity(); 8932001f49Smrg glFrustum (left + dx, right + dx, bottom + dy, top + dy, nnear, ffar); 9032001f49Smrg glMatrixMode(GL_MODELVIEW); 9132001f49Smrg glLoadIdentity(); 9232001f49Smrg glTranslatef (-eyedx, -eyedy, 0.0); 9332001f49Smrg} 9432001f49Smrg 9532001f49Smrg/* accPerspective() 9632001f49Smrg * 9732001f49Smrg * The first 4 arguments are identical to the gluPerspective() call. 9832001f49Smrg * pixdx and pixdy are anti-alias jitter in pixels. 9932001f49Smrg * Set both equal to 0.0 for no anti-alias jitter. 10032001f49Smrg * eyedx and eyedy are depth-of field jitter in pixels. 10132001f49Smrg * Set both equal to 0.0 for no depth of field effects. 10232001f49Smrg * 10332001f49Smrg * focus is distance from eye to plane in focus. 10432001f49Smrg * focus must be greater than, but not equal to 0.0. 10532001f49Smrg * 10632001f49Smrg * Note that accPerspective() calls accFrustum(). 10732001f49Smrg */ 10832001f49Smrgstatic void accPerspective(GLdouble fovy, GLdouble aspect, 10932001f49Smrg GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy, 11032001f49Smrg GLdouble eyedx, GLdouble eyedy, GLdouble focus) 11132001f49Smrg{ 11232001f49Smrg GLdouble fov2,left,right,bottom,top; 11332001f49Smrg 11432001f49Smrg fov2 = ((fovy*PI_) / 180.0) / 2.0; 11532001f49Smrg 11632001f49Smrg top = nnear / (cos(fov2) / sin(fov2)); 11732001f49Smrg bottom = -top; 11832001f49Smrg 11932001f49Smrg right = top * aspect; 12032001f49Smrg left = -right; 12132001f49Smrg 12232001f49Smrg accFrustum (left, right, bottom, top, nnear, ffar, 12332001f49Smrg pixdx, pixdy, eyedx, eyedy, focus); 12432001f49Smrg} 12532001f49Smrg 12632001f49Smrgstatic void myinit(void) 12732001f49Smrg{ 12832001f49Smrg GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 }; 12932001f49Smrg GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; 13032001f49Smrg GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 }; 13132001f49Smrg 13232001f49Smrg GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 }; 13332001f49Smrg GLfloat local_view[] = { 0.0 }; 13432001f49Smrg 13532001f49Smrg glEnable(GL_DEPTH_TEST); 13632001f49Smrg glDepthFunc(GL_LESS); 13732001f49Smrg 13832001f49Smrg glLightfv(GL_LIGHT0, GL_AMBIENT, ambient); 13932001f49Smrg glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse); 14032001f49Smrg glLightfv(GL_LIGHT0, GL_POSITION, position); 14132001f49Smrg 14232001f49Smrg glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); 14332001f49Smrg glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view); 14432001f49Smrg 14532001f49Smrg glFrontFace (GL_CW); 14632001f49Smrg glEnable(GL_LIGHTING); 14732001f49Smrg glEnable(GL_LIGHT0); 14832001f49Smrg glEnable(GL_AUTO_NORMAL); 14932001f49Smrg glEnable(GL_NORMALIZE); 15032001f49Smrg 15132001f49Smrg glMatrixMode (GL_MODELVIEW); 15232001f49Smrg glLoadIdentity (); 15332001f49Smrg 15432001f49Smrg glClearColor(0.0, 0.0, 0.0, 0.0); 15532001f49Smrg glClearAccum(0.0, 0.0, 0.0, 0.0); 15632001f49Smrg} 15732001f49Smrg 15832001f49Smrgstatic void renderTeapot (GLfloat x, GLfloat y, GLfloat z, 15932001f49Smrg GLfloat ambr, GLfloat ambg, GLfloat ambb, 16032001f49Smrg GLfloat difr, GLfloat difg, GLfloat difb, 16132001f49Smrg GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine) 16232001f49Smrg{ 16332001f49Smrg float mat[4]; 16432001f49Smrg 16532001f49Smrg glPushMatrix(); 16632001f49Smrg glTranslatef (x, y, z); 16732001f49Smrg mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0; 16832001f49Smrg glMaterialfv (GL_FRONT, GL_AMBIENT, mat); 16932001f49Smrg mat[0] = difr; mat[1] = difg; mat[2] = difb; 17032001f49Smrg glMaterialfv (GL_FRONT, GL_DIFFUSE, mat); 17132001f49Smrg mat[0] = specr; mat[1] = specg; mat[2] = specb; 17232001f49Smrg glMaterialfv (GL_FRONT, GL_SPECULAR, mat); 17332001f49Smrg glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0); 17432001f49Smrg glutSolidTeapot(0.5); 17532001f49Smrg glPopMatrix(); 17632001f49Smrg} 17732001f49Smrg 17832001f49Smrg/* display() draws 5 teapots into the accumulation buffer 17932001f49Smrg * several times; each time with a jittered perspective. 18032001f49Smrg * The focal point is at z = 5.0, so the gold teapot will 18132001f49Smrg * stay in focus. The amount of jitter is adjusted by the 18232001f49Smrg * magnitude of the accPerspective() jitter; in this example, 0.33. 18332001f49Smrg * In this example, the teapots are drawn 8 times. See jitter.h 18432001f49Smrg */ 18532001f49Smrgstatic void display(void) 18632001f49Smrg{ 18732001f49Smrg int jitter; 18832001f49Smrg GLint viewport[4]; 18932001f49Smrg 19032001f49Smrg glGetIntegerv (GL_VIEWPORT, viewport); 19132001f49Smrg glClear(GL_ACCUM_BUFFER_BIT); 19232001f49Smrg 19332001f49Smrg for (jitter = 0; jitter < 8; jitter++) { 19432001f49Smrg glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 19532001f49Smrg accPerspective (45.0, 19632001f49Smrg (GLdouble) viewport[2]/(GLdouble) viewport[3], 19732001f49Smrg 1.0, 15.0, 0.0, 0.0, 19832001f49Smrg 0.33*j8[jitter].x, 0.33*j8[jitter].y, 5.0); 19932001f49Smrg/* ruby, gold, silver, emerald, and cyan teapots */ 20032001f49Smrg renderTeapot (-1.1, -0.5, -4.5, 0.1745, 0.01175, 0.01175, 20132001f49Smrg 0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6); 20232001f49Smrg renderTeapot (-0.5, -0.5, -5.0, 0.24725, 0.1995, 0.0745, 20332001f49Smrg 0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4); 20432001f49Smrg renderTeapot (0.2, -0.5, -5.5, 0.19225, 0.19225, 0.19225, 20532001f49Smrg 0.50754, 0.50754, 0.50754, 0.508273, 0.508273, 0.508273, 0.4); 20632001f49Smrg renderTeapot (1.0, -0.5, -6.0, 0.0215, 0.1745, 0.0215, 20732001f49Smrg 0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633, 0.6); 20832001f49Smrg renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0, 0.50980392, 20932001f49Smrg 0.50980392, 0.50196078, 0.50196078, 0.50196078, .25); 21032001f49Smrg glAccum (GL_ACCUM, 0.125); 21132001f49Smrg } 21232001f49Smrg 21332001f49Smrg glAccum (GL_RETURN, 1.0); 21432001f49Smrg glFlush(); 21532001f49Smrg} 21632001f49Smrg 21732001f49Smrgstatic void myReshape(int w, int h) 21832001f49Smrg{ 21932001f49Smrg glViewport(0, 0, w, h); 22032001f49Smrg} 22132001f49Smrg 22232001f49Smrgstatic void 22332001f49Smrgkey(unsigned char k, int x, int y) 22432001f49Smrg{ 22532001f49Smrg switch (k) { 22632001f49Smrg case 27: /* Escape */ 22732001f49Smrg exit(0); 22832001f49Smrg break; 22932001f49Smrg default: 23032001f49Smrg return; 23132001f49Smrg } 23232001f49Smrg glutPostRedisplay(); 23332001f49Smrg} 23432001f49Smrg 23532001f49Smrg/* Main Loop 23632001f49Smrg * Open window with initial window size, title bar, 23732001f49Smrg * RGBA display mode, depth buffer, and handle input events. 23832001f49Smrg */ 23932001f49Smrgint main(int argc, char** argv) 24032001f49Smrg{ 24132001f49Smrg glutInit(&argc, argv); 24232001f49Smrg glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB 24332001f49Smrg | GLUT_ACCUM | GLUT_DEPTH); 24432001f49Smrg glutCreateWindow (argv[0]); 24532001f49Smrg myinit(); 24632001f49Smrg glutReshapeFunc(myReshape); 24732001f49Smrg glutDisplayFunc(display); 24832001f49Smrg glutKeyboardFunc(key); 24932001f49Smrg glutMainLoop(); 25032001f49Smrg return 0; /* ANSI C requires main to return int. */ 25132001f49Smrg} 252