1 /*
2  * Copyright (c) 1993-1997, Silicon Graphics, Inc.
3  * ALL RIGHTS RESERVED
4  * Permission to use, copy, modify, and distribute this software for
5  * any purpose and without fee is hereby granted, provided that the above
6  * copyright notice appear in all copies and that both the copyright notice
7  * and this permission notice appear in supporting documentation, and that
8  * the name of Silicon Graphics, Inc. not be used in advertising
9  * or publicity pertaining to distribution of the software without specific,
10  * written prior permission.
11  *
12  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
13  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
14  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
15  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
16  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
17  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
18  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
19  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
20  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
21  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
22  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
23  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
24  *
25  * US Government Users Restricted Rights
26  * Use, duplication, or disclosure by the Government is subject to
27  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
28  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
29  * clause at DFARS 252.227-7013 and/or in similar or successor
30  * clauses in the FAR or the DOD or NASA FAR Supplement.
31  * Unpublished-- rights reserved under the copyright laws of the
32  * United States.  Contractor/manufacturer is Silicon Graphics,
33  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
34  *
35  * OpenGL(R) is a registered trademark of Silicon Graphics, Inc.
36  */
37 
38 /*
39  *  polyoff.c
40  *  This program demonstrates polygon offset to draw a shaded
41  *  polygon and its wireframe counterpart without ugly visual
42  *  artifacts ("stitching").
43  */
44 #include "glut_wrap.h"
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #ifdef GL_VERSION_1_1
50 GLuint list;
51 GLint fill = 1;
52 GLfloat spinx = 0;
53 GLfloat spiny = 0;
54 GLfloat tdist = 0.0;
55 GLfloat polyfactor = 1.0;
56 GLfloat polyunits = 1.0;
57 GLboolean doubleBuffer;
58 
59 
60 /*  display() draws two spheres, one with a gray, diffuse material,
61  *  the other sphere with a magenta material with a specular highlight.
62  */
display(void)63 static void display (void)
64 {
65     GLfloat gray[] = { 0.8, 0.8, 0.8, 1.0 };
66     GLfloat black[] = { 0.0, 0.0, 0.0, 1.0 };
67 
68     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
69     glPushMatrix ();
70     glTranslatef (0.0, 0.0, tdist);
71     glRotatef ((GLfloat) spinx, 1.0, 0.0, 0.0);
72     glRotatef ((GLfloat) spiny, 0.0, 1.0, 0.0);
73 
74     glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, gray);
75     glMaterialfv(GL_FRONT, GL_SPECULAR, black);
76     glMaterialf(GL_FRONT, GL_SHININESS, 0.0);
77     if (fill) {
78        glEnable(GL_LIGHTING);
79        glEnable(GL_LIGHT0);
80        glEnable(GL_POLYGON_OFFSET_FILL);
81        glPolygonOffset(polyfactor, polyunits);
82        glCallList (list);
83        glDisable(GL_POLYGON_OFFSET_FILL);
84     }
85 
86     glDisable(GL_LIGHTING);
87     glDisable(GL_LIGHT0);
88     glColor3f (1.0, 1.0, 1.0);
89     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
90     glPolygonOffset(-polyfactor, -polyunits);
91     if (!fill) glEnable(GL_POLYGON_OFFSET_LINE);
92     glCallList (list);
93     glDisable(GL_POLYGON_OFFSET_LINE);
94     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
95 
96     if (!fill) {
97        glEnable(GL_LIGHTING);
98        glEnable(GL_LIGHT0);
99        glCallList (list);
100     }
101 
102     glPopMatrix ();
103     glFlush ();
104     if (doubleBuffer) glutSwapBuffers();
105 }
106 
107 /*  specify initial properties
108  *  create display list with sphere
109  *  initialize lighting and depth buffer
110  */
gfxinit(void)111 static void gfxinit (void)
112 {
113     GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
114     GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 };
115     GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 };
116     GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 };
117 
118     GLfloat global_ambient[] = { 0.2, 0.2, 0.2, 1.0 };
119 
120     glClearColor (0.0, 0.0, 0.0, 1.0);
121 
122     list = glGenLists(1);
123     glNewList (list, GL_COMPILE);
124        glutSolidSphere(1.0, 20, 12);
125     glEndList ();
126 
127     glEnable(GL_DEPTH_TEST);
128 
129     glLightfv (GL_LIGHT0, GL_AMBIENT, light_ambient);
130     glLightfv (GL_LIGHT0, GL_DIFFUSE, light_diffuse);
131     glLightfv (GL_LIGHT0, GL_SPECULAR, light_specular);
132     glLightfv (GL_LIGHT0, GL_POSITION, light_position);
133     glLightModelfv (GL_LIGHT_MODEL_AMBIENT, global_ambient);
134 }
135 
136 /*  call when window is resized  */
reshape(int width,int height)137 static void reshape(int width, int height)
138 {
139     glViewport (0, 0, width, height);
140     glMatrixMode (GL_PROJECTION);
141     glLoadIdentity ();
142     gluPerspective(45.0, (GLdouble)width/(GLdouble)height,
143 	    1.0, 10.0);
144     glMatrixMode (GL_MODELVIEW);
145     glLoadIdentity ();
146     gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
147 }
148 
Benchmark(float xdiff,float ydiff)149 static void Benchmark( float xdiff, float ydiff )
150 {
151    int startTime, endTime;
152    int draws;
153    double seconds, fps;
154 
155    printf("Benchmarking...\n");
156    fflush(stdout);
157 
158    draws = 0;
159    startTime = glutGet(GLUT_ELAPSED_TIME);
160    spinx = spiny = 0.0;
161    do {
162       spinx += xdiff;
163       spiny += ydiff;
164       display();
165       draws++;
166       endTime = glutGet(GLUT_ELAPSED_TIME);
167    } while (endTime - startTime < 5000);   /* 5 seconds */
168 
169    /* Results */
170    seconds = (double) (endTime - startTime) / 1000.0;
171    fps = draws / seconds;
172    printf("Result:  fps: %g\n", fps);
173    fflush(stdout);
174 }
175 
176 
177 /*  call when mouse button is pressed  */
178 /* ARGSUSED2 */
mouse(int button,int state,int x,int y)179 static void mouse(int button, int state, int x, int y) {
180     switch (button) {
181 	case GLUT_LEFT_BUTTON:
182 	    switch (state) {
183 		case GLUT_DOWN:
184 		    spinx += 5;
185                     glutPostRedisplay();
186 		    break;
187 		default:
188 		    break;
189             }
190             break;
191 	case GLUT_MIDDLE_BUTTON:
192 	    switch (state) {
193 		case GLUT_DOWN:
194 		    spiny += 5;
195                     glutPostRedisplay();
196 		    break;
197 		default:
198 		    break;
199             }
200             break;
201 	case GLUT_RIGHT_BUTTON:
202 	    switch (state) {
203 		case GLUT_UP:
204 		    exit(0);
205 		    break;
206 		default:
207 		    break;
208             }
209             break;
210         default:
211             break;
212     }
213 }
214 
215 /* ARGSUSED1 */
keyboard(unsigned char key,int x,int y)216 static void keyboard (unsigned char key, int x, int y)
217 {
218    switch (key) {
219       case 't':
220          if (tdist < 4.0) {
221             tdist = (tdist + 0.5);
222             glutPostRedisplay();
223          }
224          break;
225       case 'T':
226          if (tdist > -5.0) {
227             tdist = (tdist - 0.5);
228             glutPostRedisplay();
229          }
230          break;
231       case 'F':
232          polyfactor = polyfactor + 0.1;
233 	 printf ("polyfactor is %f\n", polyfactor);
234          glutPostRedisplay();
235          break;
236       case 'f':
237          polyfactor = polyfactor - 0.1;
238 	 printf ("polyfactor is %f\n", polyfactor);
239          glutPostRedisplay();
240          break;
241       case 'U':
242          polyunits = polyunits + 1.0;
243 	 printf ("polyunits is %f\n", polyunits);
244          glutPostRedisplay();
245          break;
246       case 'u':
247          polyunits = polyunits - 1.0;
248 	 printf ("polyunits is %f\n", polyunits);
249          glutPostRedisplay();
250          break;
251       case 'b':
252 	 Benchmark(5.0, 0);
253 	 break;
254       case 'B':
255 	 Benchmark(0, 5.0);
256 	 break;
257       case ' ':
258 	 fill = !fill;
259 	 printf ("fill/line: %d\n", fill);
260          glutPostRedisplay();
261          break;
262       case 27:  /* Escape */
263          exit(0);
264          break;
265       default:
266          break;
267    }
268    fflush(stdout);
269 }
270 
Args(int argc,char ** argv)271 static GLenum Args(int argc, char **argv)
272 {
273     GLint i;
274 
275     doubleBuffer = GL_FALSE;
276 
277     for (i = 1; i < argc; i++) {
278         if (strcmp(argv[i], "-sb") == 0) {
279 	    doubleBuffer = GL_FALSE;
280 	} else if (strcmp(argv[i], "-db") == 0) {
281 	    doubleBuffer = GL_TRUE;
282 	} else {
283 	    printf("%s (Bad option).\n", argv[i]);
284 	    return GL_FALSE;
285 	}
286     }
287     return GL_TRUE;
288 }
289 
290 
291 /*  Main Loop
292  *  Open window with initial window size, title bar,
293  *  RGBA display mode, and handle input events.
294  */
main(int argc,char ** argv)295 int main(int argc, char** argv)
296 {
297     GLuint type;
298     glutInit(&argc, argv);
299 
300     Args(argc, argv);
301 
302     type = GLUT_DEPTH | GLUT_RGB;
303      type |= (doubleBuffer) ? GLUT_DOUBLE : GLUT_SINGLE;
304 
305     glutInitDisplayMode(type);
306     glutCreateWindow("polyoff");
307     glutReshapeFunc(reshape);
308     glutDisplayFunc(display);
309     glutMouseFunc(mouse);
310     glutKeyboardFunc(keyboard);
311     gfxinit();
312     glutMainLoop();
313     return 0;
314 }
315 #else
main(int argc,char ** argv)316 int main(int argc, char** argv)
317 {
318     fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n");
319     fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n");
320     fprintf (stderr, "you may be able to modify this program to make it run.\n");
321     return 0;
322 }
323 #endif
324