progs/tests: also test stencil INCR_WRAP mode if supported
[mesa.git] / progs / tests / vparray.c
1 /*
2 * Test vertex arrays with GL_NV_vertex_program
3 *
4 * Based on a stripped-down version of the isosurf demo.
5 * The vertex program is trivial: compute the resulting
6 * RGB color as a linear function of vertex XYZ.
7 */
8
9 #include <assert.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <math.h>
14 #include "GL/glew.h"
15 #include "GL/glut.h"
16
17 #define MAXVERTS 10000
18 static float data[MAXVERTS][6];
19 static GLint numverts;
20
21 static GLfloat xrot;
22 static GLfloat yrot;
23 static GLboolean useArrays = GL_TRUE;
24 static GLboolean useProgram = GL_TRUE;
25 static GLboolean useList = GL_FALSE;
26
27
28 static void read_surface( char *filename )
29 {
30 FILE *f;
31
32 f = fopen(filename,"r");
33 if (!f) {
34 printf("couldn't read %s\n", filename);
35 exit(1);
36 }
37
38 numverts = 0;
39 while (numverts < MAXVERTS) {
40 int result;
41 result = fscanf( f, "%f %f %f %f %f %f",
42 &data[numverts][0], &data[numverts][1], &data[numverts][2],
43 &data[numverts][3], &data[numverts][4], &data[numverts][5] );
44 if (result == EOF) {
45 break;
46 }
47 numverts++;
48 }
49
50 printf("%d vertices, %d triangles\n", numverts, numverts-2);
51 printf("data = %p\n", (void *) data);
52 fclose(f);
53 }
54
55
56
57
58 static void Display(void)
59 {
60 if (useProgram)
61 glEnable(GL_VERTEX_PROGRAM_NV);
62 else
63 glDisable(GL_VERTEX_PROGRAM_NV);
64
65 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
66
67 glPushMatrix();
68 glRotatef(xrot, 1, 0, 0);
69 glRotatef(yrot, 0, 1, 0);
70 glScalef(2, 2, 2);
71 if (useArrays) {
72 if (useProgram) {
73 glVertexAttribPointerNV( 0, 3, GL_FLOAT, 6 * sizeof(GLfloat), data );
74 glEnableClientState( GL_VERTEX_ATTRIB_ARRAY0_NV );
75 glVertexAttribPointerNV( 2, 3, GL_FLOAT, 6 * sizeof(GLfloat), ((GLfloat *) data) + 3);
76 glEnableClientState( GL_VERTEX_ATTRIB_ARRAY2_NV);
77 }
78 else {
79 glVertexPointer( 3, GL_FLOAT, 6 * sizeof(GLfloat), data );
80 glEnableClientState( GL_VERTEX_ARRAY );
81 glNormalPointer( GL_FLOAT, 6 * sizeof(GLfloat), ((GLfloat *) data) + 3);
82 glEnableClientState( GL_NORMAL_ARRAY );
83 }
84
85 if (useList) {
86 /* dumb, but a good test */
87 glNewList(1,GL_COMPILE);
88 glDrawArrays(GL_TRIANGLE_STRIP, 0, numverts);
89 glEndList();
90 glCallList(1);
91 }
92 else {
93 glDrawArrays(GL_TRIANGLE_STRIP, 0, numverts);
94 }
95
96 glDisableClientState( GL_VERTEX_ATTRIB_ARRAY0_NV );
97 glDisableClientState( GL_VERTEX_ATTRIB_ARRAY2_NV);
98 glDisableClientState( GL_VERTEX_ARRAY );
99 glDisableClientState( GL_NORMAL_ARRAY );
100 }
101 else {
102 int i;
103 glBegin(GL_TRIANGLE_STRIP);
104 for (i = 0; i < numverts; i++) {
105 glNormal3fv( data[i] + 3 );
106 glVertex3fv( data[i] + 0 );
107 }
108 glEnd();
109 }
110 glPopMatrix();
111
112 if (glGetError())
113 printf("Error!\n");
114
115 glutSwapBuffers();
116 }
117
118
119 static void InitMaterials(void)
120 {
121 static float ambient[] = {0.1, 0.1, 0.1, 1.0};
122 static float diffuse[] = {0.5, 1.0, 1.0, 1.0};
123 static float position0[] = {0.0, 0.0, 20.0, 0.0};
124 static float position1[] = {0.0, 0.0, -20.0, 0.0};
125 static float front_mat_shininess[] = {60.0};
126 static float front_mat_specular[] = {0.2, 0.2, 0.2, 1.0};
127 static float front_mat_diffuse[] = {0.5, 0.28, 0.38, 1.0};
128 /*
129 static float back_mat_shininess[] = {60.0};
130 static float back_mat_specular[] = {0.5, 0.5, 0.2, 1.0};
131 static float back_mat_diffuse[] = {1.0, 1.0, 0.2, 1.0};
132 */
133 static float lmodel_ambient[] = {1.0, 1.0, 1.0, 1.0};
134 static float lmodel_twoside[] = {GL_FALSE};
135
136 glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
137 glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
138 glLightfv(GL_LIGHT0, GL_POSITION, position0);
139 glEnable(GL_LIGHT0);
140
141 glLightfv(GL_LIGHT1, GL_AMBIENT, ambient);
142 glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse);
143 glLightfv(GL_LIGHT1, GL_POSITION, position1);
144 glEnable(GL_LIGHT1);
145
146 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient);
147 glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE, lmodel_twoside);
148
149 glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, front_mat_shininess);
150 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, front_mat_specular);
151 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, front_mat_diffuse);
152 glEnable(GL_LIGHTING);
153 }
154
155
156 static void init_program(void)
157 {
158 /*
159 * c[0..3] = modelview matrix
160 * c[4..7] = inverse modelview matrix
161 * c[30] = color scale
162 * c[31] = color bias
163 */
164 static const char prog[] =
165 "!!VP1.0\n"
166
167 "# RGB is proportional to XYZ \n"
168
169 "MUL R0, v[OPOS], c[30]; \n"
170 "ADD o[COL0], R0, c[31]; \n"
171
172 "# Continue with typical modelview/projection\n"
173 "MOV R3, v[OPOS]; \n"
174 "DP4 o[HPOS].x, c[0], R3 ; # object x MVP -> clip\n"
175 "DP4 o[HPOS].y, c[1], R3 ;\n"
176 "DP4 o[HPOS].z, c[2], R3 ;\n"
177 "DP4 o[HPOS].w, c[3], R3 ;\n"
178
179 "END";
180
181 static const GLfloat scale[4] = {2.0, 2.0, 2.0, 0.0};
182 static const GLfloat bias[4] = {1.0, 1.0, 1.0, 0.0};
183
184 if (!glutExtensionSupported("GL_NV_vertex_program")) {
185 printf("Sorry, this program requires GL_NV_vertex_program\n");
186 exit(1);
187 }
188
189 glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1,
190 strlen(prog), (const GLubyte *) prog);
191 assert(glIsProgramNV(1));
192 glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1);
193
194 /* Load the program registers */
195 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
196 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV);
197
198 glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 30, scale);
199 glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 31, bias);
200 }
201
202
203 static void init(void)
204 {
205 xrot = 0;
206 yrot = 0;
207 glClearColor(0.0, 0.0, 1.0, 0.0);
208 glEnable( GL_DEPTH_TEST );
209 glEnable(GL_NORMALIZE);
210 InitMaterials();
211 read_surface( "../demos/isosurf.dat" );
212 init_program();
213 }
214
215
216 static void Reshape(int width, int height)
217 {
218 glViewport(0, 0, (GLint)width, (GLint)height);
219 glMatrixMode(GL_PROJECTION);
220 glLoadIdentity();
221 glFrustum( -1.0, 1.0, -1.0, 1.0, 5, 25 );
222 glMatrixMode(GL_MODELVIEW);
223 glLoadIdentity();
224 glTranslatef(0, 0, -15);
225 }
226
227
228
229 static void Key( unsigned char key, int x, int y )
230 {
231 (void) x;
232 (void) y;
233 switch (key) {
234 case 27:
235 exit(0);
236 case 'a':
237 useArrays = !useArrays;
238 printf("use arrays: %s\n", useArrays ? "yes" : "no");
239 break;
240 case 'l':
241 useList = !useList;
242 printf("use list: %s\n", useList ? "yes" : "no");
243 break;
244 case 'p':
245 useProgram = !useProgram;
246 printf("use program: %s\n", useProgram ? "yes" : "no");
247 break;
248 }
249 glutPostRedisplay();
250 }
251
252
253 static void SpecialKey( int key, int x, int y )
254 {
255 (void) x;
256 (void) y;
257 switch (key) {
258 case GLUT_KEY_LEFT:
259 yrot -= 15.0;
260 break;
261 case GLUT_KEY_RIGHT:
262 yrot += 15.0;
263 break;
264 case GLUT_KEY_UP:
265 xrot += 15.0;
266 break;
267 case GLUT_KEY_DOWN:
268 xrot -= 15.0;
269 break;
270 default:
271 return;
272 }
273 glutPostRedisplay();
274 }
275
276
277
278 int main(int argc, char **argv)
279 {
280 glutInit(&argc, argv);
281 glutInitDisplayMode( GLUT_DEPTH | GLUT_RGB | GLUT_DOUBLE );
282 glutInitWindowPosition(0, 0);
283 glutInitWindowSize(400, 400);
284 if (glutCreateWindow("Isosurface") <= 0) {
285 exit(0);
286 }
287 glewInit();
288 glutReshapeFunc(Reshape);
289 glutKeyboardFunc(Key);
290 glutSpecialFunc(SpecialKey);
291 glutDisplayFunc(Display);
292
293 init();
294
295 glutMainLoop();
296 return 0;
297 }