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