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