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