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 NAMED_PARAMETER4FV(FragProg
, "LightPos", LightPos
);
41 glEnable(GL_FRAGMENT_PROGRAM_NV
);
42 glEnable(GL_VERTEX_PROGRAM_NV
);
43 glDisable(GL_LIGHTING
);
46 glLightfv(GL_LIGHT0
, GL_POSITION
, LightPos
);
47 glDisable(GL_FRAGMENT_PROGRAM_NV
);
48 glDisable(GL_VERTEX_PROGRAM_NV
);
49 glEnable(GL_LIGHTING
);
53 glRotatef(Xrot
, 1, 0, 0);
54 glRotatef(Yrot
, 0, 1, 0);
57 glutSolidSphere(2.0, 10, 5);
60 GLUquadricObj
*q
= gluNewQuadric();
61 gluQuadricNormals(q
, GL_SMOOTH
);
62 gluQuadricTexture(q
, GL_TRUE
);
63 glRotatef(90, 1, 0, 0);
64 glTranslatef(0, 0, -1);
65 gluCylinder(q
, 1.0, 1.0, 2.0, 24, 1);
76 static void Idle(void)
79 if (LightPos
[0] > 25.0)
81 else if (LightPos
[0] <- 25.0)
87 static void Reshape( int width
, int height
)
89 glViewport( 0, 0, width
, height
);
90 glMatrixMode( GL_PROJECTION
);
92 glFrustum( -1.0, 1.0, -1.0, 1.0, 5.0, 25.0 );
93 /*glOrtho( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 );*/
94 glMatrixMode( GL_MODELVIEW
);
96 glTranslatef( 0.0, 0.0, -15.0 );
100 static void Key( unsigned char key
, int x
, int y
)
121 glPolygonMode(GL_FRONT_AND_BACK
, GL_LINE
);
123 glPolygonMode(GL_FRONT_AND_BACK
, GL_FILL
);
126 PixelLight
= !PixelLight
;
128 printf("Per-pixel lighting\n");
131 printf("Conventional lighting\n");
141 static void SpecialKey( int key
, int x
, int y
)
143 const GLfloat step
= 3.0;
164 static void Init( void )
166 static const char *fragProgramText
=
168 "DECLARE Diffuse; \n"
169 "DECLARE Specular; \n"
170 "DECLARE LightPos; \n"
172 "# Compute normalized LightPos, put it in R0\n"
173 "DP3 R0.x, LightPos, LightPos;\n"
175 "MUL R0, LightPos, R0.y;\n"
177 "# Compute normalized normal, put it in R1\n"
178 "DP3 R1, f[TEX0], f[TEX0]; \n"
180 "MUL R1, f[TEX0], R1.y;\n"
182 "# Compute dot product of light direction and normal vector\n"
183 "DP3_SAT R2, R0, R1;"
185 "MUL R3, Diffuse, R2; # diffuse attenuation\n"
187 "POW R4, R2.x, {20.0}.x; # specular exponent\n"
189 "MUL R5, Specular, R4; # specular attenuation\n"
191 "ADD o[COLR], R3, R5; # add diffuse and specular colors\n"
195 static const char *vertProgramText
=
197 "# typical modelview/projection transform\n"
198 "DP4 o[HPOS].x, c[0], v[OPOS] ;\n"
199 "DP4 o[HPOS].y, c[1], v[OPOS] ;\n"
200 "DP4 o[HPOS].z, c[2], v[OPOS] ;\n"
201 "DP4 o[HPOS].w, c[3], v[OPOS] ;\n"
202 "# transform normal by inv transpose of modelview, put in tex0\n"
203 "DP3 o[TEX0].x, c[4], v[NRML] ;\n"
204 "DP3 o[TEX0].y, c[5], v[NRML] ;\n"
205 "DP3 o[TEX0].z, c[6], v[NRML] ;\n"
206 "DP3 o[TEX0].w, c[7], v[NRML] ;\n"
210 if (!glutExtensionSupported("GL_NV_vertex_program")) {
211 printf("Sorry, this demo requires GL_NV_vertex_program\n");
214 if (!glutExtensionSupported("GL_NV_fragment_program")) {
215 printf("Sorry, this demo requires GL_NV_fragment_program\n");
219 glGenProgramsNV(1, &FragProg
);
220 assert(FragProg
> 0);
221 glGenProgramsNV(1, &VertProg
);
222 assert(VertProg
> 0);
227 glLoadProgramNV(GL_FRAGMENT_PROGRAM_NV
, FragProg
,
228 strlen(fragProgramText
),
229 (const GLubyte
*) fragProgramText
);
230 assert(glIsProgramNV(FragProg
));
231 glBindProgramNV(GL_FRAGMENT_PROGRAM_NV
, FragProg
);
233 NAMED_PARAMETER4FV(FragProg
, "Diffuse", Diffuse
);
234 NAMED_PARAMETER4FV(FragProg
, "Specular", Specular
);
239 glLoadProgramNV(GL_VERTEX_PROGRAM_NV
, VertProg
,
240 strlen(vertProgramText
),
241 (const GLubyte
*) vertProgramText
);
242 assert(glIsProgramNV(VertProg
));
243 glBindProgramNV(GL_VERTEX_PROGRAM_NV
, VertProg
);
244 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV
, 0, GL_MODELVIEW_PROJECTION_NV
, GL_IDENTITY_NV
);
245 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV
, 4, GL_MODELVIEW
, GL_INVERSE_TRANSPOSE_NV
);
250 glClearColor(0.3, 0.3, 0.3, 0.0);
251 glEnable(GL_DEPTH_TEST
);
253 glEnable(GL_LIGHTING
);
254 glMaterialfv(GL_FRONT_AND_BACK
, GL_DIFFUSE
, Diffuse
);
255 glMaterialfv(GL_FRONT_AND_BACK
, GL_SPECULAR
, Specular
);
256 glMaterialf(GL_FRONT_AND_BACK
, GL_SHININESS
, 20.0);
258 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER
));
259 printf("Press p to toggle between per-pixel and per-vertex lighting\n");
263 int main( int argc
, char *argv
[] )
265 glutInit( &argc
, argv
);
266 glutInitWindowPosition( 0, 0 );
267 glutInitWindowSize( 200, 200 );
268 glutInitDisplayMode( GLUT_RGB
| GLUT_DOUBLE
| GLUT_DEPTH
);
269 glutCreateWindow(argv
[0]);
270 glutReshapeFunc( Reshape
);
271 glutKeyboardFunc( Key
);
272 glutSpecialFunc( SpecialKey
);
273 glutDisplayFunc( Display
);