/* Copyright (c) Mark J. Kilgard, 1994. */ /** * (c) Copyright 1993, 1994, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(TM) is a trademark of Silicon Graphics, Inc. */ #include #include #include #include #include /* Some files do not define M_PI... */ #ifndef M_PI #define M_PI 3.14159265 #endif #define TWO_PI (2*M_PI) typedef struct lightRec { float amb[4]; float diff[4]; float spec[4]; float pos[4]; float spotDir[3]; float spotExp; float spotCutoff; float atten[3]; float trans[3]; float rot[3]; float swing[3]; float arc[3]; float arcIncr[3]; } Light; static int useSAME_AMB_SPEC = 1; /* *INDENT-OFF* */ static float modelAmb[4] = {0.2, 0.2, 0.2, 1.0}; static float matAmb[4] = {0.2, 0.2, 0.2, 1.0}; static float matDiff[4] = {0.8, 0.8, 0.8, 1.0}; static float matSpec[4] = {0.4, 0.4, 0.4, 1.0}; static float matEmission[4] = {0.0, 0.0, 0.0, 1.0}; /* *INDENT-ON* */ #define NUM_LIGHTS 3 static Light spots[] = { { {0.2, 0.0, 0.0, 1.0}, /* ambient */ {0.8, 0.0, 0.0, 1.0}, /* diffuse */ {0.4, 0.0, 0.0, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ {20.0}, {60.0}, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 70.0, 0.0, TWO_PI / 140.0} /* arc increment */ }, { {0.0, 0.2, 0.0, 1.0}, /* ambient */ {0.0, 0.8, 0.0, 1.0}, /* diffuse */ {0.0, 0.4, 0.0, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ {20.0}, {60.0}, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 120.0, 0.0, TWO_PI / 60.0} /* arc increment */ }, { {0.0, 0.0, 0.2, 1.0}, /* ambient */ {0.0, 0.0, 0.8, 1.0}, /* diffuse */ {0.0, 0.0, 0.4, 1.0}, /* specular */ {0.0, 0.0, 0.0, 1.0}, /* position */ {0.0, -1.0, 0.0}, /* direction */ {20.0}, {60.0}, /* exponent, cutoff */ {1.0, 0.0, 0.0}, /* attenuation */ {0.0, 1.25, 0.0}, /* translation */ {0.0, 0.0, 0.0}, /* rotation */ {20.0, 0.0, 40.0}, /* swing */ {0.0, 0.0, 0.0}, /* arc */ {TWO_PI / 50.0, 0.0, TWO_PI / 100.0} /* arc increment */ } }; static void usage(char *name) { printf("\n"); printf("usage: %s [options]\n", name); printf("\n"); printf(" Options:\n"); printf(" -geometry Specify size and position WxH+X+Y\n"); printf(" -lm Toggle lighting(SPECULAR and AMBIENT are/not same\n"); printf("\n"); #ifndef EXIT_FAILURE /* should be defined by ANSI C */ #define EXIT_FAILURE 1 #endif exit(EXIT_FAILURE); } static void initLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glEnable(lt); glLightfv(lt, GL_AMBIENT, light->amb); glLightfv(lt, GL_DIFFUSE, light->diff); if (useSAME_AMB_SPEC) glLightfv(lt, GL_SPECULAR, light->amb); else glLightfv(lt, GL_SPECULAR, light->spec); glLightf(lt, GL_SPOT_EXPONENT, light->spotExp); glLightf(lt, GL_SPOT_CUTOFF, light->spotCutoff); glLightf(lt, GL_CONSTANT_ATTENUATION, light->atten[0]); glLightf(lt, GL_LINEAR_ATTENUATION, light->atten[1]); glLightf(lt, GL_QUADRATIC_ATTENUATION, light->atten[2]); } } static void aimLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; light->rot[0] = light->swing[0] * sin(light->arc[0]); light->arc[0] += light->arcIncr[0]; if (light->arc[0] > TWO_PI) light->arc[0] -= TWO_PI; light->rot[1] = light->swing[1] * sin(light->arc[1]); light->arc[1] += light->arcIncr[1]; if (light->arc[1] > TWO_PI) light->arc[1] -= TWO_PI; light->rot[2] = light->swing[2] * sin(light->arc[2]); light->arc[2] += light->arcIncr[2]; if (light->arc[2] > TWO_PI) light->arc[2] -= TWO_PI; } } static void setLights(void) { int k; for (k = 0; k < NUM_LIGHTS; ++k) { int lt = GL_LIGHT0 + k; Light *light = &spots[k]; glPushMatrix(); glTranslatef(light->trans[0], light->trans[1], light->trans[2]); glRotatef(light->rot[0], 1, 0, 0); glRotatef(light->rot[1], 0, 1, 0); glRotatef(light->rot[2], 0, 0, 1); glLightfv(lt, GL_POSITION, light->pos); glLightfv(lt, GL_SPOT_DIRECTION, light->spotDir); glPopMatrix(); } } static void drawLights(void) { int k; glDisable(GL_LIGHTING); for (k = 0; k < NUM_LIGHTS; ++k) { Light *light = &spots[k]; glColor4fv(light->diff); glPushMatrix(); glTranslatef(light->trans[0], light->trans[1], light->trans[2]); glRotatef(light->rot[0], 1, 0, 0); glRotatef(light->rot[1], 0, 1, 0); glRotatef(light->rot[2], 0, 0, 1); glBegin(GL_LINES); glVertex3f(light->pos[0], light->pos[1], light->pos[2]); glVertex3f(light->spotDir[0], light->spotDir[1], light->spotDir[2]); glEnd(); glPopMatrix(); } glEnable(GL_LIGHTING); } static void drawPlane(int w, int h) { int i, j; float dw = 1.0 / w; float dh = 1.0 / h; glNormal3f(0.0, 0.0, 1.0); for (j = 0; j < h; ++j) { glBegin(GL_TRIANGLE_STRIP); for (i = 0; i <= w; ++i) { glVertex2f(dw * i, dh * (j + 1)); glVertex2f(dw * i, dh * j); } glEnd(); } } int spin = 0; void display(void) { glClear(GL_COLOR_BUFFER_BIT); glPushMatrix(); glRotatef(spin, 0, 1, 0); aimLights(); setLights(); glPushMatrix(); glRotatef(-90.0, 1, 0, 0); glScalef(1.9, 1.9, 1.0); glTranslatef(-0.5, -0.5, 0.0); drawPlane(16, 16); glPopMatrix(); drawLights(); glPopMatrix(); glutSwapBuffers(); } void animate(void) { spin += 0.5; if (spin > 360.0) spin -= 360.0; glutPostRedisplay(); } void visibility(int state) { if (state == GLUT_VISIBLE) { glutIdleFunc(animate); } else { glutIdleFunc(NULL); } } int main(int argc, char **argv) { int i; glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); /* process commmand line args */ for (i = 1; i < argc; ++i) { if (!strcmp("-lm", argv[i])) { useSAME_AMB_SPEC = !useSAME_AMB_SPEC; } else { usage(argv[0]); } } glutCreateWindow("GLUT spotlight swing"); glutDisplayFunc(display); glutVisibilityFunc(visibility); glMatrixMode(GL_PROJECTION); glFrustum(-1, 1, -1, 1, 2, 6); glMatrixMode(GL_MODELVIEW); glTranslatef(0.0, 0.0, -3.0); glRotatef(45.0, 1, 0, 0); glEnable(GL_LIGHTING); glEnable(GL_NORMALIZE); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb); glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); glMaterialfv(GL_FRONT, GL_AMBIENT, matAmb); glMaterialfv(GL_FRONT, GL_DIFFUSE, matDiff); glMaterialfv(GL_FRONT, GL_SPECULAR, matSpec); glMaterialfv(GL_FRONT, GL_EMISSION, matEmission); glMaterialf(GL_FRONT, GL_SHININESS, 10.0); initLights(); glutMainLoop(); return 0; /* ANSI C requires main to return int. */ }