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 /* borrowed from an nvidia demo: 108 * c[0..3] = modelview matrix 109 * c[4..7] = inverse modelview matrix 110 * c[32] = light pos 111 * c[35] = diffuse color 112 */ 113 static const char prog[] = 114 "!!VP1.0\n" 115 "#Simple transform and diffuse lighting\n" 116 "\n" 117 "DP4 o[HPOS].x, c[0], v[OPOS] ; # object x MVP -> clip\n" 118 "DP4 o[HPOS].y, c[1], v[OPOS] ;\n" 119 "DP4 o[HPOS].z, c[2], v[OPOS] ;\n" 120 "DP4 o[HPOS].w, c[3], v[OPOS] ;\n" 121 122 "DP3 R1.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" 123 "DP3 R1.y, c[5], v[NRML] ;\n" 124 "DP3 R1.z, c[6], v[NRML] ;\n" 125 126 "DP3 R0, c[32], R1 ; # L.N\n" 127 "MUL o[COL0].xyz, R0, c[35] ; # col = L.N * diffuse\n" 128 "MOV o[TEX0], v[TEX0];\n" 129 "END"; 130 131 if (!glutExtensionSupported("GL_NV_vertex_program")) { 132 printf("Sorry, this program requires GL_NV_vertex_program"); 133 exit(1); 134 } 135 136 glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1, 137 strlen(prog), (const GLubyte *) prog); 138 assert(glIsProgramNV(1)); 139 glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1); 140 141 /* Load the program registers */ 142 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); 143 glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV); 144 145 /* Light position */ 146 glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 32, 2, 2, 4, 1); 147 /* Diffuse material color */ 148 glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 35, 0.25, 0, 0.25, 1); 149 150 glEnable(GL_VERTEX_PROGRAM_NV); 151 glEnable(GL_DEPTH_TEST); 152 glClearColor(0.3, 0.3, 0.3, 1); 153 154 printf("glGetError = %d\n", (int) glGetError()); 155} 156 157 158int main( int argc, char *argv[] ) 159{ 160 glutInit( &argc, argv ); 161 glutInitWindowPosition( 0, 0 ); 162 glutInitWindowSize( 250, 250 ); 163 glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 164 glutCreateWindow(argv[0]); 165 glewInit(); 166 glutReshapeFunc( Reshape ); 167 glutKeyboardFunc( Key ); 168 glutSpecialFunc( SpecialKey ); 169 glutDisplayFunc( Display ); 170 if (Anim) 171 glutIdleFunc(Idle); 172 Init(); 173 glutMainLoop(); 174 return 0; 175} 176