st/mesa: fix incorrect RowStride computation
[mesa.git] / progs / vp / vp-tris.c
1 /* Test glGenProgramsNV(), glIsProgramNV(), glLoadProgramNV() */
2
3 #include <assert.h>
4 #include <string.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <math.h>
8
9 #ifndef WIN32
10 #include <unistd.h>
11 #include <signal.h>
12 #endif
13
14 #include <GL/glew.h>
15 #include <GL/glut.h>
16
17 static const char *filename = NULL;
18 static GLuint nr_steps = 4;
19 static GLuint prim = GL_TRIANGLES;
20 static GLfloat psz = 1.0;
21 static GLboolean pointsmooth = 0;
22 static GLboolean program_point_size = 0;
23
24 static void usage( char *name )
25 {
26 fprintf( stderr, "usage: %s [ options ] shader_filename\n", name );
27 fprintf( stderr, "\n" );
28 fprintf( stderr, "options:\n" );
29 fprintf( stderr, " -f flat shaded\n" );
30 fprintf( stderr, " -nNr subdivision steps\n" );
31 fprintf( stderr, " -fps show frames per second\n" );
32 }
33
34 unsigned show_fps = 0;
35 unsigned int frame_cnt = 0;
36
37 #ifndef WIN32
38
39 void alarmhandler(int);
40
41 void alarmhandler (int sig)
42 {
43 if (sig == SIGALRM) {
44 printf("%d frames in 5.0 seconds = %.3f FPS\n", frame_cnt,
45 frame_cnt / 5.0);
46
47 frame_cnt = 0;
48 }
49 signal(SIGALRM, alarmhandler);
50 alarm(5);
51 }
52
53 #endif
54
55 static void args(int argc, char *argv[])
56 {
57 GLint i;
58
59 for (i = 1; i < argc; i++) {
60 if (strncmp(argv[i], "-n", 2) == 0) {
61 nr_steps = atoi((argv[i]) + 2);
62 }
63 else if (strcmp(argv[i], "-f") == 0) {
64 glShadeModel(GL_FLAT);
65 }
66 else if (strcmp(argv[i], "-fps") == 0) {
67 show_fps = 1;
68 }
69 else if (i == argc - 1) {
70 filename = argv[i];
71 }
72 else {
73 usage(argv[0]);
74 exit(1);
75 }
76 }
77
78 if (!filename) {
79 usage(argv[0]);
80 exit(1);
81 }
82 }
83
84
85
86 static void Init( void )
87 {
88 GLint errno;
89 GLuint prognum;
90 char buf[4096];
91 GLuint sz;
92 FILE *f;
93
94 if ((f = fopen(filename, "r")) == NULL) {
95 fprintf(stderr, "couldn't open %s\n", filename);
96 exit(1);
97 }
98
99 sz = (GLuint) fread(buf, 1, sizeof(buf) - 1, f);
100 buf[sizeof(buf) - 1] = '\0';
101 if (!feof(f)) {
102 fprintf(stderr, "file too long\n");
103 fclose(f);
104 exit(1);
105 }
106
107 fclose(f);
108 fprintf(stderr, "%.*s\n", sz, buf);
109
110 if (strncmp( buf, "!!VP", 4 ) == 0) {
111 glEnable( GL_VERTEX_PROGRAM_NV );
112 glGenProgramsNV( 1, &prognum );
113 glBindProgramNV( GL_VERTEX_PROGRAM_NV, prognum );
114 glLoadProgramNV( GL_VERTEX_PROGRAM_NV, prognum, sz, (const GLubyte *) buf );
115 assert( glIsProgramNV( prognum ) );
116 }
117 else {
118 glEnable(GL_VERTEX_PROGRAM_ARB);
119
120 glGenProgramsARB(1, &prognum);
121
122 glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
123 glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
124 sz, (const GLubyte *) buf);
125 if (glGetError()) {
126 printf("Program failed to compile:\n%s\n", buf);
127 printf("Error: %s\n",
128 (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
129 exit(1);
130 }
131 assert(glIsProgramARB(prognum));
132 }
133
134 errno = glGetError();
135 printf("glGetError = %d\n", errno);
136 if (errno != GL_NO_ERROR)
137 {
138 GLint errorpos;
139
140 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos);
141 printf("errorpos: %d\n", errorpos);
142 printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB));
143 }
144
145 {
146 const float Ambient[4] = { 0.0, 1.0, 0.0, 0.0 };
147 const float Diffuse[4] = { 1.0, 0.0, 0.0, 0.0 };
148 const float Specular[4] = { 0.0, 0.0, 1.0, 0.0 };
149 const float Emission[4] = { 0.0, 0.0, 0.0, 1.0 };
150 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Ambient);
151 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Diffuse);
152 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Specular);
153 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, Emission);
154 }
155 }
156
157
158 union vert {
159 struct {
160 GLfloat color[3];
161 GLfloat pos[3];
162 } v;
163 GLfloat f[6];
164 };
165
166 static void make_midpoint( union vert *out,
167 const union vert *v0,
168 const union vert *v1)
169 {
170 int i;
171 for (i = 0; i < 6; i++)
172 out->f[i] = v0->f[i] + .5 * (v1->f[i] - v0->f[i]);
173 }
174
175 static void subdiv( union vert *v0,
176 union vert *v1,
177 union vert *v2,
178 GLuint depth )
179 {
180 if (depth == 0) {
181 glColor3fv(v0->v.color);
182 glVertex3fv(v0->v.pos);
183 glColor3fv(v1->v.color);
184 glVertex3fv(v1->v.pos);
185 glColor3fv(v2->v.color);
186 glVertex3fv(v2->v.pos);
187 }
188 else {
189 union vert m[3];
190
191 make_midpoint(&m[0], v0, v1);
192 make_midpoint(&m[1], v1, v2);
193 make_midpoint(&m[2], v2, v0);
194
195 subdiv(&m[0], &m[2], v0, depth-1);
196 subdiv(&m[1], &m[0], v1, depth-1);
197 subdiv(&m[2], &m[1], v2, depth-1);
198 subdiv(&m[0], &m[1], &m[2], depth-1);
199 }
200 }
201
202 static void enable( GLenum value, GLboolean flag )
203 {
204 if (flag)
205 glEnable(value);
206 else
207 glDisable(value);
208 }
209
210 /** Assignment */
211 #define ASSIGN_3V( V, V0, V1, V2 ) \
212 do { \
213 V[0] = V0; \
214 V[1] = V1; \
215 V[2] = V2; \
216 } while(0)
217
218 static void Display( void )
219 {
220 glClearColor(0.3, 0.3, 0.3, 1);
221 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
222 glPointSize(psz);
223
224 enable( GL_POINT_SMOOTH, pointsmooth );
225 enable( GL_VERTEX_PROGRAM_POINT_SIZE_ARB, program_point_size );
226
227 glBegin(prim);
228
229
230 {
231 union vert v[3];
232
233 ASSIGN_3V(v[0].v.color, 0,0,1);
234 ASSIGN_3V(v[0].v.pos, 0.9, -0.9, 0.0);
235 ASSIGN_3V(v[1].v.color, 1,0,0);
236 ASSIGN_3V(v[1].v.pos, 0.9, 0.9, 0.0);
237 ASSIGN_3V(v[2].v.color, 0,1,0);
238 ASSIGN_3V(v[2].v.pos, -0.9, 0, 0.0);
239
240 subdiv(&v[0], &v[1], &v[2], nr_steps);
241 }
242
243 glEnd();
244
245
246 glFlush();
247 if (show_fps) {
248 ++frame_cnt;
249 glutPostRedisplay();
250 }
251 }
252
253
254 static void Reshape( int width, int height )
255 {
256 glViewport( 0, 0, width, height );
257 glMatrixMode( GL_PROJECTION );
258 glLoadIdentity();
259 glOrtho(-1.0, 1.0, -1.0, 1.0, -0.5, 1000.0);
260 glMatrixMode( GL_MODELVIEW );
261 glLoadIdentity();
262 /*glTranslatef( 0.0, 0.0, -15.0 );*/
263 }
264
265
266 static void Key( unsigned char key, int x, int y )
267 {
268 (void) x;
269 (void) y;
270 switch (key) {
271 case 'p':
272 prim = GL_POINTS;
273 break;
274 case 't':
275 prim = GL_TRIANGLES;
276 break;
277 case 's':
278 psz += .5;
279 break;
280 case 'S':
281 if (psz > .5)
282 psz -= .5;
283 break;
284 case 'm':
285 pointsmooth = !pointsmooth;
286 break;
287 case 'z':
288 program_point_size = !program_point_size;
289 break;
290 case '+':
291 nr_steps++;
292 break;
293 case '-':
294 if (nr_steps)
295 nr_steps--;
296 break;
297 case ' ':
298 psz = 1.0;
299 prim = GL_TRIANGLES;
300 nr_steps = 4;
301 break;
302 case 27:
303 exit(0);
304 break;
305 }
306 glutPostRedisplay();
307 }
308
309
310
311
312 int main( int argc, char *argv[] )
313 {
314 glutInit( &argc, argv );
315 glutInitWindowPosition( 0, 0 );
316 glutInitWindowSize( 250, 250 );
317 glutInitDisplayMode( GLUT_RGB | GLUT_SINGLE | GLUT_DEPTH );
318 glutCreateWindow(argv[argc-1]);
319 glewInit();
320 glutReshapeFunc( Reshape );
321 glutKeyboardFunc( Key );
322 glutDisplayFunc( Display );
323 args( argc, argv );
324 Init();
325 #ifndef WIN32
326 if (show_fps) {
327 signal(SIGALRM, alarmhandler);
328 alarm(5);
329 }
330 #endif
331 glutMainLoop();
332 return 0;
333 }