blob: 1c513cf0f41c78e566c028379d3bcf277cebbc5f [file] [log] [blame]
Brian Paul62954c82002-04-22 15:53:54 +00001/*
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
19static float data[MAXVERTS][6];
20static GLint numverts;
21
22static GLfloat xrot;
23static GLfloat yrot;
Brian Paul919404f2004-01-31 19:15:43 +000024static GLboolean useArrays = GL_TRUE;
25static GLboolean useProgram = GL_TRUE;
Brian Paul62954c82002-04-22 15:53:54 +000026
27
28static 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
55static 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 );
Brian Paul62dc8022003-05-30 15:38:26 +000072 glVertexAttribPointerNV( 2, 3, GL_FLOAT, 6 * sizeof(GLfloat), ((GLfloat *) data) + 3);
73 glEnableClientState( GL_VERTEX_ATTRIB_ARRAY2_NV);
Brian Paul62954c82002-04-22 15:53:54 +000074 }
75 else {
76 glVertexPointer( 3, GL_FLOAT, 6 * sizeof(GLfloat), data );
77 glEnableClientState( GL_VERTEX_ARRAY );
Brian Paul62dc8022003-05-30 15:38:26 +000078 glNormalPointer( GL_FLOAT, 6 * sizeof(GLfloat), ((GLfloat *) data) + 3);
79 glEnableClientState( GL_NORMAL_ARRAY );
Brian Paul62954c82002-04-22 15:53:54 +000080 }
Brian Paul62954c82002-04-22 15:53:54 +000081
82 glDrawArrays(GL_TRIANGLE_STRIP, 0, numverts);
83
84 glDisableClientState( GL_VERTEX_ATTRIB_ARRAY0_NV );
Brian Paul919404f2004-01-31 19:15:43 +000085 glDisableClientState( GL_VERTEX_ATTRIB_ARRAY2_NV);
Brian Paul62954c82002-04-22 15:53:54 +000086 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
107static 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
144static 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
191static 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
204static 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
217static 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
237static 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
262int 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}