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