-/* ARGSUSED2 */\r
-static void\r
-mouse(int button, int state, int x, int y)\r
-{\r
- if (button == GLUT_LEFT_BUTTON) {\r
- if (state == GLUT_DOWN) {\r
- moving = 1;\r
- startx = x;\r
- starty = y;\r
- }\r
- if (state == GLUT_UP) {\r
- moving = 0;\r
- }\r
- }\r
- if (button == GLUT_MIDDLE_BUTTON) {\r
- if (state == GLUT_DOWN) {\r
- lightMoving = 1;\r
- lightStartX = x;\r
- lightStartY = y;\r
- }\r
- if (state == GLUT_UP) {\r
- lightMoving = 0;\r
- }\r
- }\r
-}\r
-\r
-/* ARGSUSED1 */\r
-static void\r
-motion(int x, int y)\r
-{\r
- if (moving) {\r
- angle = angle + (x - startx);\r
- angle2 = angle2 + (y - starty);\r
- startx = x;\r
- starty = y;\r
- glutPostRedisplay();\r
- }\r
- if (lightMoving) {\r
- lightAngle += (x - lightStartX)/40.0;\r
- lightHeight += (lightStartY - y)/20.0;\r
- lightStartX = x;\r
- lightStartY = y;\r
- glutPostRedisplay();\r
- }\r
-}\r
-\r
-/* Advance time varying state when idle callback registered. */\r
-static void\r
-idle(void)\r
-{\r
- static float time = 0.0;\r
-\r
- time = glutGet(GLUT_ELAPSED_TIME) / 500.0;\r
-\r
- jump = 4.0 * fabs(sin(time)*0.5);\r
- if (!lightMoving) {\r
- lightAngle += 0.03;\r
- }\r
- glutPostRedisplay();\r
-}\r
-\r
-enum {\r
- M_NONE, M_MOTION, M_LIGHT, M_TEXTURE, M_SHADOWS, M_REFLECTION, M_DINOSAUR,\r
- M_STENCIL_REFLECTION, M_STENCIL_SHADOW, M_OFFSET_SHADOW,\r
- M_POSITIONAL, M_DIRECTIONAL, M_PERFORMANCE\r
-};\r
-\r
-static void\r
-controlLights(int value)\r
-{\r
- switch (value) {\r
- case M_NONE:\r
- return;\r
- case M_MOTION:\r
- animation = 1 - animation;\r
- if (animation) {\r
- glutIdleFunc(idle);\r
- } else {\r
- glutIdleFunc(NULL);\r
- }\r
- break;\r
- case M_LIGHT:\r
- lightSwitch = !lightSwitch;\r
- if (lightSwitch) {\r
- glEnable(GL_LIGHT0);\r
- } else {\r
- glDisable(GL_LIGHT0);\r
- }\r
- break;\r
- case M_TEXTURE:\r
- useTexture = !useTexture;\r
- break;\r
- case M_SHADOWS:\r
- renderShadow = 1 - renderShadow;\r
- break;\r
- case M_REFLECTION:\r
- renderReflection = 1 - renderReflection;\r
- break;\r
- case M_DINOSAUR:\r
- renderDinosaur = 1 - renderDinosaur;\r
- break;\r
- case M_STENCIL_REFLECTION:\r
- stencilReflection = 1 - stencilReflection;\r
- break;\r
- case M_STENCIL_SHADOW:\r
- stencilShadow = 1 - stencilShadow;\r
- break;\r
- case M_OFFSET_SHADOW:\r
- offsetShadow = 1 - offsetShadow;\r
- break;\r
- case M_POSITIONAL:\r
- directionalLight = 0;\r
- break;\r
- case M_DIRECTIONAL:\r
- directionalLight = 1;\r
- break;\r
- case M_PERFORMANCE:\r
- reportSpeed = 1 - reportSpeed;\r
- break;\r
- }\r
- glutPostRedisplay();\r
-}\r
-\r
-/* When not visible, stop animating. Restart when visible again. */\r
-static void\r
-visible(int vis)\r
-{\r
- if (vis == GLUT_VISIBLE) {\r
- if (animation)\r
- glutIdleFunc(idle);\r
- } else {\r
- if (!animation)\r
- glutIdleFunc(NULL);\r
- }\r
-}\r
-\r
-/* Press any key to redraw; good when motion stopped and\r
- performance reporting on. */\r
-/* ARGSUSED */\r
-static void\r
-key(unsigned char c, int x, int y)\r
-{\r
- if (c == 27) {\r
- exit(0); /* IRIS GLism, Escape quits. */\r
- }\r
- glutPostRedisplay();\r
-}\r
-\r
-/* Press any key to redraw; good when motion stopped and\r
- performance reporting on. */\r
-/* ARGSUSED */\r
-static void\r
-special(int k, int x, int y)\r
-{\r
- glutPostRedisplay();\r
-}\r
-\r
-static int\r
-supportsOneDotOne(void)\r
-{\r
- const char *version;\r
- int major, minor;\r
-\r
- version = (char *) glGetString(GL_VERSION);\r
- if (sscanf(version, "%d.%d", &major, &minor) == 2)\r
- return major >= 1 && minor >= 1;\r
- return 0; /* OpenGL version string malformed! */\r
-}\r
-\r
-int\r
-main(int argc, char **argv)\r
-{\r
- int i;\r
-\r
- glutInit(&argc, argv);\r
-\r
- for (i=1; i<argc; i++) {\r
- if (!strcmp("-linear", argv[i])) {\r
- linearFiltering = 1;\r
- } else if (!strcmp("-mipmap", argv[i])) {\r
- useMipmaps = 1;\r
- } else if (!strcmp("-ext", argv[i])) {\r
- forceExtension = 1;\r
- }\r
- }\r
-\r
- glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL | GLUT_MULTISAMPLE);\r
-\r
-#if 1\r
- /* In GLUT 4.0, you'll be able to do this an be sure to\r
- get 2 bits of stencil if the machine has it for you. */\r
- glutInitDisplayString("samples stencil>=2 rgb double depth");\r
-#endif\r
-\r
- glutCreateWindow("Shadowy Leapin' Lizards");\r
-\r
- if (glutGet(GLUT_WINDOW_STENCIL_SIZE) <= 1) {\r
- printf("dinoshade: Sorry, I need at least 2 bits of stencil.\n");\r
- exit(1);\r
- }\r
-\r
- /* Register GLUT callbacks. */\r
- glutDisplayFunc(redraw);\r
- glutMouseFunc(mouse);\r
- glutMotionFunc(motion);\r
- glutVisibilityFunc(visible);\r
- glutKeyboardFunc(key);\r
- glutSpecialFunc(special);\r
-\r
- glutCreateMenu(controlLights);\r
-\r
- glutAddMenuEntry("Toggle motion", M_MOTION);\r
- glutAddMenuEntry("-----------------------", M_NONE);\r
- glutAddMenuEntry("Toggle light", M_LIGHT);\r
- glutAddMenuEntry("Toggle texture", M_TEXTURE);\r
- glutAddMenuEntry("Toggle shadows", M_SHADOWS);\r
- glutAddMenuEntry("Toggle reflection", M_REFLECTION);\r
- glutAddMenuEntry("Toggle dinosaur", M_DINOSAUR);\r
- glutAddMenuEntry("-----------------------", M_NONE);\r
- glutAddMenuEntry("Toggle reflection stenciling", M_STENCIL_REFLECTION);\r
- glutAddMenuEntry("Toggle shadow stenciling", M_STENCIL_SHADOW);\r
- glutAddMenuEntry("Toggle shadow offset", M_OFFSET_SHADOW);\r
- glutAddMenuEntry("----------------------", M_NONE);\r
- glutAddMenuEntry("Positional light", M_POSITIONAL);\r
- glutAddMenuEntry("Directional light", M_DIRECTIONAL);\r
- glutAddMenuEntry("-----------------------", M_NONE);\r
- glutAddMenuEntry("Toggle performance", M_PERFORMANCE);\r
- glutAttachMenu(GLUT_RIGHT_BUTTON);\r
- makeDinosaur();\r
-\r
-#ifdef GL_VERSION_1_1\r
- if (supportsOneDotOne() && !forceExtension) {\r
- polygonOffsetVersion = ONE_DOT_ONE;\r
- glPolygonOffset(-2.0, -1.0);\r
- } else\r
-#endif\r
- {\r
-#ifdef GL_EXT_polygon_offset\r
- /* check for the polygon offset extension */\r
- if (glutExtensionSupported("GL_EXT_polygon_offset")) {\r
- polygonOffsetVersion = EXTENSION;\r
- glPolygonOffsetEXT(-0.1, -0.002);\r
- } else\r
-#endif\r
- {\r
- polygonOffsetVersion = MISSING;\r
- printf("\ndinoshine: Missing polygon offset.\n");\r
- printf(" Expect shadow depth aliasing artifacts.\n\n");\r
- }\r
- }\r
-\r