Remove a bunch of really old/obsolete configs.
[mesa.git] / progs / demos / fplight.c
1 /*
2 * Use GL_NV_fragment_program to implement per-pixel lighting.
3 *
4 * Brian Paul
5 * 7 April 2003
6 */
7
8 #include <assert.h>
9 #include <string.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <math.h>
13 #define GL_GLEXT_PROTOTYPES
14 #include <GL/glut.h>
15
16
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;
21
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;
27
28 static GLfloat Xrot = 0, Yrot = 0;
29
30
31 #define NAMED_PARAMETER4FV(prog, name, v) \
32 glProgramNamedParameter4fvNV(prog, strlen(name), (const GLubyte *) name, v)
33
34
35 static void Display( void )
36 {
37 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
38
39 if (PixelLight) {
40 NAMED_PARAMETER4FV(FragProg, "LightPos", LightPos);
41 glEnable(GL_FRAGMENT_PROGRAM_NV);
42 glEnable(GL_VERTEX_PROGRAM_NV);
43 glDisable(GL_LIGHTING);
44 }
45 else {
46 glLightfv(GL_LIGHT0, GL_POSITION, LightPos);
47 glDisable(GL_FRAGMENT_PROGRAM_NV);
48 glDisable(GL_VERTEX_PROGRAM_NV);
49 glEnable(GL_LIGHTING);
50 }
51
52 glPushMatrix();
53 glRotatef(Xrot, 1, 0, 0);
54 glRotatef(Yrot, 0, 1, 0);
55
56 #if 1
57 glutSolidSphere(2.0, 10, 5);
58 #else
59 {
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);
66 gluDeleteQuadric(q);
67 }
68 #endif
69
70 glPopMatrix();
71
72 glutSwapBuffers();
73 }
74
75
76 static void Idle(void)
77 {
78 LightPos[0] += Delta;
79 if (LightPos[0] > 25.0)
80 Delta = -1.0;
81 else if (LightPos[0] <- 25.0)
82 Delta = 1.0;
83 glutPostRedisplay();
84 }
85
86
87 static void Reshape( int width, int height )
88 {
89 glViewport( 0, 0, width, height );
90 glMatrixMode( GL_PROJECTION );
91 glLoadIdentity();
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 );
95 glLoadIdentity();
96 glTranslatef( 0.0, 0.0, -15.0 );
97 }
98
99
100 static void Key( unsigned char key, int x, int y )
101 {
102 (void) x;
103 (void) y;
104 switch (key) {
105 case ' ':
106 Anim = !Anim;
107 if (Anim)
108 glutIdleFunc(Idle);
109 else
110 glutIdleFunc(NULL);
111 break;
112 case 'x':
113 LightPos[0] -= 1.0;
114 break;
115 case 'X':
116 LightPos[0] += 1.0;
117 break;
118 case 'w':
119 Wire = !Wire;
120 if (Wire)
121 glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
122 else
123 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
124 break;
125 case 'p':
126 PixelLight = !PixelLight;
127 if (PixelLight) {
128 printf("Per-pixel lighting\n");
129 }
130 else {
131 printf("Conventional lighting\n");
132 }
133 break;
134 case 27:
135 exit(0);
136 break;
137 }
138 glutPostRedisplay();
139 }
140
141 static void SpecialKey( int key, int x, int y )
142 {
143 const GLfloat step = 3.0;
144 (void) x;
145 (void) y;
146 switch (key) {
147 case GLUT_KEY_UP:
148 Xrot -= step;
149 break;
150 case GLUT_KEY_DOWN:
151 Xrot += step;
152 break;
153 case GLUT_KEY_LEFT:
154 Yrot -= step;
155 break;
156 case GLUT_KEY_RIGHT:
157 Yrot += step;
158 break;
159 }
160 glutPostRedisplay();
161 }
162
163
164 static void Init( void )
165 {
166 static const char *fragProgramText =
167 "!!FP1.0\n"
168 "DECLARE Diffuse; \n"
169 "DECLARE Specular; \n"
170 "DECLARE LightPos; \n"
171
172 "# Compute normalized LightPos, put it in R0\n"
173 "DP3 R0.x, LightPos, LightPos;\n"
174 "RSQ R0.y, R0.x;\n"
175 "MUL R0, LightPos, R0.y;\n"
176
177 "# Compute normalized normal, put it in R1\n"
178 "DP3 R1, f[TEX0], f[TEX0]; \n"
179 "RSQ R1.y, R1.x;\n"
180 "MUL R1, f[TEX0], R1.y;\n"
181
182 "# Compute dot product of light direction and normal vector\n"
183 "DP3 R2, R0, R1;"
184
185 "MUL R3, Diffuse, R2; # diffuse attenuation\n"
186
187 "POW R4, R2.x, {20.0}.x; # specular exponent\n"
188
189 "MUL R5, Specular, R4; # specular attenuation\n"
190
191 "ADD o[COLR], R3, R5; # add diffuse and specular colors\n"
192 "END \n"
193 ;
194
195 static const char *vertProgramText =
196 "!!VP1.0\n"
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 "DP4 o[TEX0].x, c[4], v[NRML] ;\n"
204 "DP4 o[TEX0].y, c[5], v[NRML] ;\n"
205 "DP4 o[TEX0].z, c[6], v[NRML] ;\n"
206 "DP4 o[TEX0].w, c[7], v[NRML] ;\n"
207 "END\n";
208 ;
209
210 if (!glutExtensionSupported("GL_NV_vertex_program")) {
211 printf("Sorry, this demo requires GL_NV_vertex_program\n");
212 exit(1);
213 }
214 if (!glutExtensionSupported("GL_NV_fragment_program")) {
215 printf("Sorry, this demo requires GL_NV_fragment_program\n");
216 exit(1);
217 }
218
219 glGenProgramsNV(1, &FragProg);
220 assert(FragProg > 0);
221 glGenProgramsNV(1, &VertProg);
222 assert(VertProg > 0);
223
224 /*
225 * Fragment program
226 */
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);
232
233 NAMED_PARAMETER4FV(FragProg, "Diffuse", Diffuse);
234 NAMED_PARAMETER4FV(FragProg, "Specular", Specular);
235
236 /*
237 * Vertex program
238 */
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);
246
247 /*
248 * Misc init
249 */
250 glClearColor(0.3, 0.3, 0.3, 0.0);
251 glEnable(GL_DEPTH_TEST);
252 glEnable(GL_LIGHT0);
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);
257
258 printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
259 printf("Press p to toggle between per-pixel and per-vertex lighting\n");
260 }
261
262
263 int main( int argc, char *argv[] )
264 {
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 );
274 if (Anim)
275 glutIdleFunc(Idle);
276 Init();
277 glutMainLoop();
278 return 0;
279 }