1
2/* Copyright (c) Mark J. Kilgard, 1994. */
3
4/*
5 * (c) Copyright 1993, Silicon Graphics, Inc.
6 * ALL RIGHTS RESERVED
7 * Permission to use, copy, modify, and distribute this software for
8 * any purpose and without fee is hereby granted, provided that the above
9 * copyright notice appear in all copies and that both the copyright notice
10 * and this permission notice appear in supporting documentation, and that
11 * the name of Silicon Graphics, Inc. not be used in advertising
12 * or publicity pertaining to distribution of the software without specific,
13 * written prior permission.
14 *
15 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
16 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
18 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
19 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
20 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
21 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
22 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
23 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
24 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
25 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
26 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
27 *
28 * US Government Users Restricted Rights
29 * Use, duplication, or disclosure by the Government is subject to
30 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
31 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
32 * clause at DFARS 252.227-7013 and/or in similar or successor
33 * clauses in the FAR or the DOD or NASA FAR Supplement.
34 * Unpublished-- rights reserved under the copyright laws of the
35 * United States.  Contractor/manufacturer is Silicon Graphics,
36 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
37 *
38 * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
39 */
40/*
41 *  dof.c
42 *  This program demonstrates use of the accumulation buffer to
43 *  create an out-of-focus depth-of-field effect.  The teapots
44 *  are drawn several times into the accumulation buffer.  The
45 *  viewing volume is jittered, except at the focal point, where
46 *  the viewing volume is at the same position, each time.  In
47 *  this case, the gold teapot remains in focus.
48 */
49#include <stdlib.h>
50#include <math.h>
51#include "glut_wrap.h"
52#include "jitter.h"
53
54#define PI_ 3.14159265358979323846
55
56/*	accFrustum()
57 *  The first 6 arguments are identical to the glFrustum() call.
58 *
59 *  pixdx and pixdy are anti-alias jitter in pixels.
60 *  Set both equal to 0.0 for no anti-alias jitter.
61 *  eyedx and eyedy are depth-of field jitter in pixels.
62 *  Set both equal to 0.0 for no depth of field effects.
63 *
64 *  focus is distance from eye to plane in focus.
65 *  focus must be greater than, but not equal to 0.0.
66 *
67 *  Note that accFrustum() calls glTranslatef().  You will
68 *  probably want to insure that your ModelView matrix has been
69 *  initialized to identity before calling accFrustum().
70 */
71static void accFrustum(GLdouble left, GLdouble right, GLdouble bottom,
72    GLdouble top, GLdouble nnear, GLdouble ffar, GLdouble pixdx,
73    GLdouble pixdy, GLdouble eyedx, GLdouble eyedy, GLdouble focus)
74{
75    GLdouble xwsize, ywsize;
76    GLdouble dx, dy;
77    GLint viewport[4];
78
79    glGetIntegerv (GL_VIEWPORT, viewport);
80
81    xwsize = right - left;
82    ywsize = top - bottom;
83
84    dx = -(pixdx*xwsize/(GLdouble) viewport[2] + eyedx*nnear/focus);
85    dy = -(pixdy*ywsize/(GLdouble) viewport[3] + eyedy*nnear/focus);
86
87    glMatrixMode(GL_PROJECTION);
88    glLoadIdentity();
89    glFrustum (left + dx, right + dx, bottom + dy, top + dy, nnear, ffar);
90    glMatrixMode(GL_MODELVIEW);
91    glLoadIdentity();
92    glTranslatef (-eyedx, -eyedy, 0.0);
93}
94
95/*  accPerspective()
96 *
97 *  The first 4 arguments are identical to the gluPerspective() call.
98 *  pixdx and pixdy are anti-alias jitter in pixels.
99 *  Set both equal to 0.0 for no anti-alias jitter.
100 *  eyedx and eyedy are depth-of field jitter in pixels.
101 *  Set both equal to 0.0 for no depth of field effects.
102 *
103 *  focus is distance from eye to plane in focus.
104 *  focus must be greater than, but not equal to 0.0.
105 *
106 *  Note that accPerspective() calls accFrustum().
107 */
108static void accPerspective(GLdouble fovy, GLdouble aspect,
109    GLdouble nnear, GLdouble ffar, GLdouble pixdx, GLdouble pixdy,
110    GLdouble eyedx, GLdouble eyedy, GLdouble focus)
111{
112    GLdouble fov2,left,right,bottom,top;
113
114    fov2 = ((fovy*PI_) / 180.0) / 2.0;
115
116    top = nnear / (cos(fov2) / sin(fov2));
117    bottom = -top;
118
119    right = top * aspect;
120    left = -right;
121
122    accFrustum (left, right, bottom, top, nnear, ffar,
123	pixdx, pixdy, eyedx, eyedy, focus);
124}
125
126static void myinit(void)
127{
128    GLfloat ambient[] = { 0.0, 0.0, 0.0, 1.0 };
129    GLfloat diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
130    GLfloat position[] = { 0.0, 3.0, 3.0, 0.0 };
131
132    GLfloat lmodel_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
133    GLfloat local_view[] = { 0.0 };
134
135    glEnable(GL_DEPTH_TEST);
136    glDepthFunc(GL_LESS);
137
138    glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
139    glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
140    glLightfv(GL_LIGHT0, GL_POSITION, position);
141
142    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
143    glLightModelfv(GL_LIGHT_MODEL_LOCAL_VIEWER, local_view);
144
145    glFrontFace (GL_CW);
146    glEnable(GL_LIGHTING);
147    glEnable(GL_LIGHT0);
148    glEnable(GL_AUTO_NORMAL);
149    glEnable(GL_NORMALIZE);
150
151    glMatrixMode (GL_MODELVIEW);
152    glLoadIdentity ();
153
154    glClearColor(0.0, 0.0, 0.0, 0.0);
155    glClearAccum(0.0, 0.0, 0.0, 0.0);
156}
157
158static void renderTeapot (GLfloat x, GLfloat y, GLfloat z,
159    GLfloat ambr, GLfloat ambg, GLfloat ambb,
160    GLfloat difr, GLfloat difg, GLfloat difb,
161    GLfloat specr, GLfloat specg, GLfloat specb, GLfloat shine)
162{
163    float mat[4];
164
165    glPushMatrix();
166    glTranslatef (x, y, z);
167    mat[0] = ambr; mat[1] = ambg; mat[2] = ambb; mat[3] = 1.0;
168    glMaterialfv (GL_FRONT, GL_AMBIENT, mat);
169    mat[0] = difr; mat[1] = difg; mat[2] = difb;
170    glMaterialfv (GL_FRONT, GL_DIFFUSE, mat);
171    mat[0] = specr; mat[1] = specg; mat[2] = specb;
172    glMaterialfv (GL_FRONT, GL_SPECULAR, mat);
173    glMaterialf (GL_FRONT, GL_SHININESS, shine*128.0);
174    glutSolidTeapot(0.5);
175    glPopMatrix();
176}
177
178/*  display() draws 5 teapots into the accumulation buffer
179 *  several times; each time with a jittered perspective.
180 *  The focal point is at z = 5.0, so the gold teapot will
181 *  stay in focus.  The amount of jitter is adjusted by the
182 *  magnitude of the accPerspective() jitter; in this example, 0.33.
183 *  In this example, the teapots are drawn 8 times.  See jitter.h
184 */
185static void display(void)
186{
187    int jitter;
188    GLint viewport[4];
189
190    glGetIntegerv (GL_VIEWPORT, viewport);
191    glClear(GL_ACCUM_BUFFER_BIT);
192
193    for (jitter = 0; jitter < 8; jitter++) {
194	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
195	accPerspective (45.0,
196		(GLdouble) viewport[2]/(GLdouble) viewport[3],
197		1.0, 15.0, 0.0, 0.0,
198		0.33*j8[jitter].x, 0.33*j8[jitter].y, 5.0);
199/*	ruby, gold, silver, emerald, and cyan teapots	*/
200	renderTeapot (-1.1, -0.5, -4.5, 0.1745, 0.01175, 0.01175,
201	    0.61424, 0.04136, 0.04136, 0.727811, 0.626959, 0.626959, 0.6);
202	renderTeapot (-0.5, -0.5, -5.0, 0.24725, 0.1995, 0.0745,
203	    0.75164, 0.60648, 0.22648, 0.628281, 0.555802, 0.366065, 0.4);
204	renderTeapot (0.2, -0.5, -5.5, 0.19225, 0.19225, 0.19225,
205	    0.50754, 0.50754, 0.50754, 0.508273, 0.508273, 0.508273, 0.4);
206	renderTeapot (1.0, -0.5, -6.0, 0.0215, 0.1745, 0.0215,
207	    0.07568, 0.61424, 0.07568, 0.633, 0.727811, 0.633, 0.6);
208	renderTeapot (1.8, -0.5, -6.5, 0.0, 0.1, 0.06, 0.0, 0.50980392,
209	    0.50980392, 0.50196078, 0.50196078, 0.50196078, .25);
210	glAccum (GL_ACCUM, 0.125);
211    }
212
213    glAccum (GL_RETURN, 1.0);
214    glFlush();
215}
216
217static void myReshape(int w, int h)
218{
219    glViewport(0, 0, w, h);
220}
221
222static void
223key(unsigned char k, int x, int y)
224{
225  switch (k) {
226  case 27:  /* Escape */
227    exit(0);
228    break;
229  default:
230    return;
231  }
232  glutPostRedisplay();
233}
234
235/*  Main Loop
236 *  Open window with initial window size, title bar,
237 *  RGBA display mode, depth buffer, and handle input events.
238 */
239int main(int argc, char** argv)
240{
241    glutInit(&argc, argv);
242    glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB
243			| GLUT_ACCUM | GLUT_DEPTH);
244    glutCreateWindow (argv[0]);
245    myinit();
246    glutReshapeFunc(myReshape);
247    glutDisplayFunc(display);
248    glutKeyboardFunc(key);
249    glutMainLoop();
250    return 0;             /* ANSI C requires main to return int. */
251}
252