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