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 50GLuint list; 51GLint fill = 1; 52GLfloat spinx = 0; 53GLfloat spiny = 0; 54GLfloat tdist = 0.0; 55GLfloat polyfactor = 1.0; 56GLfloat polyunits = 1.0; 57GLboolean 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 */ 63static 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 */ 111static 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 */ 137static 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 149static 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 */ 179static 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 */ 216static 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 271static 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 */ 295int 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 316int 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