windows-nt/Source/XPSP1/NT/multimedia/opengl/test/demos/misc/spots.c

316 lines
8.9 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <GL/gl.h>
#include "glaux.h"
#include "miscflt.h"
#include "miscutil.h"
#ifndef M_PI
#define M_PI 3.1415926539
#endif
#define TWO_PI ((float)(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;
static float modelAmb[4] = { POINT_TWO, POINT_TWO, POINT_TWO, ONE };
static float matAmb[4] = { POINT_TWO, POINT_TWO, POINT_TWO, ONE };
static float matDiff[4] = { POINT_EIGHT, POINT_EIGHT, POINT_EIGHT, ONE };
static float matSpec[4] = { POINT_FOUR, POINT_FOUR, POINT_FOUR, ONE };
static float matEmission[4] = { ZERO, ZERO, ZERO, ONE };
static char *geometry = NULL;
#define NUM_LIGHTS 3
static Light spots[] = {
{
{ POINT_TWO , ZERO, ZERO, ONE }, /* ambient */
{ POINT_EIGHT, ZERO, ZERO, ONE }, /* diffuse */
{ POINT_FOUR , ZERO, ZERO, ONE }, /* specular */
{ ZERO, ZERO , ZERO, ONE }, /* position */
{ ZERO, -ONE , ZERO }, /* direction */
{ 20.0f }, { 60.0f }, /* exponent, cutoff */
{ ONE, ZERO, ZERO }, /* attenuation */
{ ZERO, 1.25f, ZERO }, /* translation */
{ ZERO, ZERO, ZERO }, /* rotation */
{ 20.0f, ZERO, 40.0f }, /* swing */
{ ZERO, ZERO, ZERO }, /* arc */
{ (float)(TWO_PI/70.0), ZERO, (float)(TWO_PI/140.0) } /* arc increment */
},
{
{ ZERO, POINT_TWO, ZERO, ONE }, /* ambient */
{ ZERO, POINT_EIGHT, ZERO, ONE }, /* diffuse */
{ ZERO, POINT_FOUR, ZERO, ONE }, /* specular */
{ ZERO, ZERO, ZERO, ONE }, /* position */
{ ZERO, -ONE, ZERO }, /* direction */
{ 20.0f }, { 60.0f }, /* exponent, cutoff */
{ ONE, ZERO, ZERO }, /* attenuation */
{ ZERO, 1.25f, ZERO }, /* translation */
{ ZERO, ZERO, ZERO }, /* rotation */
{ 20.0f, ZERO, 40.0f }, /* swing */
{ ZERO, ZERO, ZERO }, /* arc */
{ (float)(TWO_PI/120.0), ZERO, (float)(TWO_PI/60.0) } /* arc increment */
},
{
{ ZERO, ZERO, POINT_TWO, ONE }, /* ambient */
{ ZERO, ZERO, POINT_EIGHT, ONE }, /* diffuse */
{ ZERO, ZERO, POINT_FOUR, ONE }, /* specular */
{ ZERO, ZERO, ZERO, ONE }, /* position */
{ ZERO, -ONE, ZERO }, /* direction */
{ 20.0f }, { 60.0f }, /* exponent, cutoff */
{ ONE, ZERO, ZERO }, /* attenuation */
{ ZERO, 1.25f, ZERO }, /* translation */
{ ZERO, ZERO, ZERO }, /* rotation */
{ 20.0f, ZERO, 40.0f }, /* swing */
{ ZERO, ZERO, ZERO }, /* arc */
{ (float)(TWO_PI/50.0), ZERO, (float)(TWO_PI/100.0) } /* arc increment */
}
};
void Display( void );
void MyReshape( GLsizei Width, GLsizei Height );
static void
usage(int argc, char **argv)
{
printf("\n");
printf("usage: %s [options]\n", argv[0]);
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");
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] * SINF(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] * SINF(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] * SINF(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], ONE, ZERO, ZERO);
glRotatef(light->rot[1], ZERO, ONE, ZERO);
glRotatef(light->rot[2], ZERO, ZERO, ONE);
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], ONE, ZERO, ZERO);
glRotatef(light->rot[1], ZERO, ONE, ZERO);
glRotatef(light->rot[2], ZERO, ZERO, ONE);
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 = ONE/w;
float dh = ONE/h;
glNormal3f(ZERO, ZERO, ONE);
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
main(int argc, char **argv)
{
int width = 300, height = 300;
int left = 50, top = 50;
int i;
/* process commmand line args */
for (i = 1; i < argc; ++i)
{
if (!strcmp("-geometry", argv[i]))
{
i++;
if ( !miscParseGeometry(argv[i],
&left,
&top,
&width,
&height )
)
{
usage(argc, argv);
}
}
else if (!strcmp("-lm", argv[i]))
{
useSAME_AMB_SPEC = !useSAME_AMB_SPEC;
}
else
{
usage(argc, argv);
}
}
auxInitPosition( left, top, width, height );
auxInitDisplayMode( AUX_RGBA | AUX_DOUBLE );
auxInitWindow( "spotlight swing" );
auxIdleFunc( Display );
auxReshapeFunc( MyReshape );
glMatrixMode(GL_PROJECTION);
glFrustum(-1.0, 1.0, -1.0, 1.0, 2.0, 6.0);
glMatrixMode(GL_MODELVIEW);
glTranslatef(ZERO, ZERO, -THREE);
glRotatef(45.0f, ONE, ZERO, ZERO);
glEnable(GL_LIGHTING);
glEnable(GL_NORMALIZE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, modelAmb);
glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, (float)GL_TRUE);
glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, (float)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, TEN);
initLights();
auxMainLoop( Display );
return(0);
}
void
Display( void )
{
static float spin = ZERO;
glClear(GL_COLOR_BUFFER_BIT);
glPushMatrix();
glRotatef(spin += 0.5f, ZERO, ONE, ZERO);
if (spin > 360.0f) spin -= 360.0f;
aimLights();
setLights();
glPushMatrix();
glRotatef(-NINETY, ONE, ZERO, ZERO);
glScalef(1.9f, 1.9f, ONE);
glTranslatef(-HALF, -HALF, ZERO);
drawPlane(16, 16);
glPopMatrix();
drawLights();
glPopMatrix();
auxSwapBuffers();
}
void
MyReshape( GLsizei Width, GLsizei Height )
{
glViewport(0, 0, Width, Height);
}