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