1/* 2 * A lit, rotating torus via vertex program 3 */ 4 5#include <assert.h> 6#include <string.h> 7#include <stdio.h> 8#include <stdlib.h> 9#include <math.h> 10#include <GL/glew.h> 11#include "glut_wrap.h" 12 13static float Xrot = 0.0, Yrot = 0.0, Zrot = 0.0; 14static GLboolean Anim = GL_TRUE; 15 16 17static void Idle( void ) 18{ 19 Xrot += .3; 20 Yrot += .4; 21 Zrot += .2; 22 glutPostRedisplay(); 23} 24 25 26static void Display( void ) 27{ 28 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 29 30 glPushMatrix(); 31 glRotatef(Xrot, 1, 0, 0); 32 glRotatef(Yrot, 0, 1, 0); 33 glRotatef(Zrot, 0, 0, 1); 34 glutSolidTorus(0.75, 2.0, 10, 20); 35 glPopMatrix(); 36 37 glutSwapBuffers(); 38} 39 40 41static void Reshape( int width, int height ) 42{ 43 glViewport( 0, 0, width, height ); 44 glMatrixMode( GL_PROJECTION ); 45 glLoadIdentity(); 46 glFrustum( -2.0, 2.0, -2.0, 2.0, 5.0, 25.0 ); 47 glMatrixMode( GL_MODELVIEW ); 48 glLoadIdentity(); 49 glTranslatef( 0.0, 0.0, -12.0 ); 50} 51 52 53static void Key( unsigned char key, int x, int y ) 54{ 55 (void) x; 56 (void) y; 57 switch (key) { 58 case ' ': 59 Xrot = Yrot = Zrot = 0; 60 break; 61 case 'a': 62 Anim = !Anim; 63 if (Anim) 64 glutIdleFunc(Idle); 65 else 66 glutIdleFunc(NULL); 67 break; 68 case 'z': 69 Zrot -= 5.0; 70 break; 71 case 'Z': 72 Zrot += 5.0; 73 break; 74 case 27: 75 exit(0); 76 break; 77 } 78 glutPostRedisplay(); 79} 80 81 82static void SpecialKey( int key, int x, int y ) 83{ 84 const GLfloat step = 3.0; 85 (void) x; 86 (void) y; 87 switch (key) { 88 case GLUT_KEY_UP: 89 Xrot -= step; 90 break; 91 case GLUT_KEY_DOWN: 92 Xrot += step; 93 break; 94 case GLUT_KEY_LEFT: 95 Yrot -= step; 96 break; 97 case GLUT_KEY_RIGHT: 98 Yrot += step; 99 break; 100 } 101 glutPostRedisplay(); 102} 103 104 105static void Init( void ) 106{ 107 GLint errnum; 108 GLuint prognum; 109 110 /* borrowed from an nvidia demo: 111 * c[0..3] = modelview matrix 112 * c[4..7] = invtrans modelview matrix 113 * c[32] = light pos 114 * c[35] = diffuse color 115 */ 116 static const char prog[] = 117 "!!ARBvp1.0\n" 118 "OPTION ARB_position_invariant ;" 119 "TEMP R0, R1; \n" 120 121 "# normal x MV-1T -> lighting normal\n" 122 "DP3 R1.x, state.matrix.modelview.invtrans.row[0], vertex.normal ;\n" 123 "DP3 R1.y, state.matrix.modelview.invtrans.row[1], vertex.normal;\n" 124 "DP3 R1.z, state.matrix.modelview.invtrans.row[2], vertex.normal;\n" 125 126 "DP3 R0, program.local[32], R1; # L.N\n" 127#if 0 128 "MUL result.color.xyz, R0, program.local[35] ; # col = L.N * diffuse\n" 129#else 130 "MUL result.color.primary.xyz, R0, program.local[35] ; # col = L.N * diffuse\n" 131#endif 132 "MOV result.texcoord, vertex.texcoord;\n" 133 "END"; 134 135 if (!glutExtensionSupported("GL_ARB_vertex_program")) { 136 printf("Sorry, this program requires GL_ARB_vertex_program"); 137 exit(1); 138 } 139 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 strlen(prog), (const GLubyte *) prog); 146 147 assert(glIsProgramARB(prognum)); 148 errnum = glGetError(); 149 printf("glGetError = %d\n", errnum); 150 if (errnum != GL_NO_ERROR) 151 { 152 GLint errorpos; 153 154 glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &errorpos); 155 printf("errorpos: %d\n", errorpos); 156 printf("%s\n", (char *)glGetString(GL_PROGRAM_ERROR_STRING_ARB)); 157 } 158 159 /* Light position */ 160 glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 32, 2, 2, 4, 1); 161 /* Diffuse material color */ 162 glProgramLocalParameter4fARB(GL_VERTEX_PROGRAM_ARB, 35, 0.25, 0, 0.25, 1); 163 164 glEnable(GL_VERTEX_PROGRAM_ARB); 165 glEnable(GL_DEPTH_TEST); 166 glClearColor(0.3, 0.3, 0.3, 1); 167} 168 169 170int main( int argc, char *argv[] ) 171{ 172 glutInit( &argc, argv ); 173 glutInitWindowPosition( 0, 0 ); 174 glutInitWindowSize( 250, 250 ); 175 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 176 glutCreateWindow(argv[0]); 177 glewInit(); 178 glutReshapeFunc( Reshape ); 179 glutKeyboardFunc( Key ); 180 glutSpecialFunc( SpecialKey ); 181 glutDisplayFunc( Display ); 182 if (Anim) 183 glutIdleFunc(Idle); 184 Init(); 185 glutMainLoop(); 186 return 0; 187} 188