2
* Use GL_NV_fragment_program to implement per-pixel lighting.
13
#define GL_GLEXT_PROTOTYPES
17
static GLfloat Diffuse[4] = { 0.5, 0.5, 1.0, 1.0 };
18
static GLfloat Specular[4] = { 0.8, 0.8, 0.8, 1.0 };
19
static GLfloat LightPos[4] = { 0.0, 10.0, 20.0, 1.0 };
20
static GLfloat Delta = 1.0;
22
static GLuint FragProg;
23
static GLuint VertProg;
24
static GLboolean Anim = GL_TRUE;
25
static GLboolean Wire = GL_FALSE;
26
static GLboolean PixelLight = GL_TRUE;
28
static GLfloat Xrot = 0, Yrot = 0;
31
#define NAMED_PARAMETER4FV(prog, name, v) \
32
glProgramNamedParameter4fvNV(prog, strlen(name), (const GLubyte *) name, v)
35
static void Display( void )
37
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
40
#if defined(GL_NV_fragment_program)
41
NAMED_PARAMETER4FV(FragProg, "LightPos", LightPos);
42
glEnable(GL_FRAGMENT_PROGRAM_NV);
43
glEnable(GL_VERTEX_PROGRAM_NV);
45
glDisable(GL_LIGHTING);
48
glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
49
#if defined(GL_NV_fragment_program)
50
glDisable(GL_FRAGMENT_PROGRAM_NV);
51
glDisable(GL_VERTEX_PROGRAM_NV);
53
glEnable(GL_LIGHTING);
57
glRotatef(Xrot, 1, 0, 0);
58
glRotatef(Yrot, 0, 1, 0);
61
glutSolidSphere(2.0, 10, 5);
64
GLUquadricObj *q = gluNewQuadric();
65
gluQuadricNormals(q, GL_SMOOTH);
66
gluQuadricTexture(q, GL_TRUE);
67
glRotatef(90, 1, 0, 0);
68
glTranslatef(0, 0, -1);
69
gluCylinder(q, 1.0, 1.0, 2.0, 24, 1);
80
static void Idle(void)
83
if (LightPos[0] > 25.0)
85
else if (LightPos[0] <- 25.0)
91
static void Reshape( int width, int height )
93
glViewport( 0, 0, width, height );
94
glMatrixMode( GL_PROJECTION );
96
glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
97
/*glOrtho( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 );*/
98
glMatrixMode( GL_MODELVIEW );
100
glTranslatef( 0.0, 0.0, -15.0 );
104
static void Key( unsigned char key, int x, int y )
125
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
127
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
130
PixelLight = !PixelLight;
132
printf("Per-pixel lighting\n");
135
printf("Conventional lighting\n");
139
glutDestroyWindow(Win);
145
static void SpecialKey( int key, int x, int y )
147
const GLfloat step = 3.0;
168
static void Init( void )
170
static const char *fragProgramText =
172
"DECLARE Diffuse; \n"
173
"DECLARE Specular; \n"
174
"DECLARE LightPos; \n"
176
"# Compute normalized LightPos, put it in R0\n"
177
"DP3 R0.x, LightPos, LightPos;\n"
179
"MUL R0, LightPos, R0.y;\n"
181
"# Compute normalized normal, put it in R1\n"
182
"DP3 R1, f[TEX0], f[TEX0]; \n"
184
"MUL R1, f[TEX0], R1.y;\n"
186
"# Compute dot product of light direction and normal vector\n"
187
"DP3_SAT R2, R0, R1;"
189
"MUL R3, Diffuse, R2; # diffuse attenuation\n"
191
"POW R4, R2.x, {20.0}.x; # specular exponent\n"
193
"MUL R5, Specular, R4; # specular attenuation\n"
195
"ADD o[COLR], R3, R5; # add diffuse and specular colors\n"
199
static const char *vertProgramText =
201
"# typical modelview/projection transform\n"
202
"DP4 o[HPOS].x, c[0], v[OPOS] ;\n"
203
"DP4 o[HPOS].y, c[1], v[OPOS] ;\n"
204
"DP4 o[HPOS].z, c[2], v[OPOS] ;\n"
205
"DP4 o[HPOS].w, c[3], v[OPOS] ;\n"
206
"# transform normal by inv transpose of modelview, put in tex0\n"
207
"DP3 o[TEX0].x, c[4], v[NRML] ;\n"
208
"DP3 o[TEX0].y, c[5], v[NRML] ;\n"
209
"DP3 o[TEX0].z, c[6], v[NRML] ;\n"
210
"DP3 o[TEX0].w, c[7], v[NRML] ;\n"
214
if (!glutExtensionSupported("GL_NV_vertex_program")) {
215
printf("Sorry, this demo requires GL_NV_vertex_program\n");
218
if (!glutExtensionSupported("GL_NV_fragment_program")) {
219
printf("Sorry, this demo requires GL_NV_fragment_program\n");
223
#if defined(GL_NV_fragment_program)
224
glGenProgramsNV(1, &FragProg);
225
assert(FragProg > 0);
226
glGenProgramsNV(1, &VertProg);
227
assert(VertProg > 0);
232
glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg,
233
strlen(fragProgramText),
234
(const GLubyte *) fragProgramText);
235
assert(glIsProgramNV(FragProg));
236
glBindProgramNV(GL_FRAGMENT_PROGRAM_NV, FragProg);
238
NAMED_PARAMETER4FV(FragProg, "Diffuse", Diffuse);
239
NAMED_PARAMETER4FV(FragProg, "Specular", Specular);
244
glLoadProgramNV(GL_VERTEX_PROGRAM_NV, VertProg,
245
strlen(vertProgramText),
246
(const GLubyte *) vertProgramText);
247
assert(glIsProgramNV(VertProg));
248
glBindProgramNV(GL_VERTEX_PROGRAM_NV, VertProg);
249
glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
250
glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV);
256
glClearColor(0.3, 0.3, 0.3, 0.0);
257
glEnable(GL_DEPTH_TEST);
259
glEnable(GL_LIGHTING);
260
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
261
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
262
glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 20.0);
264
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
265
printf("Press p to toggle between per-pixel and per-vertex lighting\n");
269
int main( int argc, char *argv[] )
271
glutInit( &argc, argv );
272
glutInitWindowPosition( 0, 0 );
273
glutInitWindowSize( 200, 200 );
274
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
275
Win = glutCreateWindow(argv[0]);
276
glutReshapeFunc( Reshape );
277
glutKeyboardFunc( Key );
278
glutSpecialFunc( SpecialKey );
279
glutDisplayFunc( Display );