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