vpwarpmesh.c revision 32001f49
1/*
2 * Warp a triangle mesh with a 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 = -60.0, Yrot = 0.0, Zrot = 0.0;
14static GLboolean Anim = GL_TRUE;
15static GLfloat Phi = 0.0;
16
17
18static void Idle( void )
19{
20   Phi += 0.01;
21   glutPostRedisplay();
22}
23
24
25static void DrawMesh( int rows, int cols )
26{
27   static const GLfloat colorA[3] = { 0, 1, 0 };
28   static const GLfloat colorB[3] = { 0, 0, 1 };
29   const float dx = 2.0 / (cols - 1);
30   const float dy = 2.0 / (rows - 1);
31   float x, y;
32   int i, j;
33
34#if 1
35#define COLOR3FV(c)     glVertexAttrib3fvNV(3, c)
36#define VERTEX2F(x, y)  glVertexAttrib2fNV(0, x, y)
37#else
38#define COLOR3FV(c)     glColor3fv(c)
39#define VERTEX2F(x, y)  glVertex2f(x, y)
40#endif
41
42   y = -1.0;
43   for (i = 0; i < rows - 1; i++) {
44      glBegin(GL_QUAD_STRIP);
45      x = -1.0;
46      for (j = 0; j < cols; j++) {
47         if ((i + j) & 1)
48            COLOR3FV(colorA);
49         else
50            COLOR3FV(colorB);
51         VERTEX2F(x, y);
52         VERTEX2F(x, y + dy);
53         x += dx;
54      }
55      glEnd();
56      y += dy;
57   }
58}
59
60
61static void Display( void )
62{
63   glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
64
65   glPushMatrix();
66      glRotatef(Xrot, 1, 0, 0);
67      glRotatef(Yrot, 0, 1, 0);
68      glRotatef(Zrot, 0, 0, 1);
69
70      /* Position the gravity source */
71      {
72         GLfloat x, y, z, r = 0.5;
73         x = r * cos(Phi);
74         y = r * sin(Phi);
75         z = 1.0;
76         glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 30, x, y, z, 1);
77         glDisable(GL_VERTEX_PROGRAM_NV);
78         glBegin(GL_POINTS);
79         glColor3f(1,1,1);
80         glVertex3f(x, y, z);
81         glEnd();
82      }
83
84      glEnable(GL_VERTEX_PROGRAM_NV);
85      DrawMesh(8, 8);
86   glPopMatrix();
87
88   glutSwapBuffers();
89}
90
91
92static void Reshape( int width, int height )
93{
94   float ar = (float) width / (float) height;
95   glViewport( 0, 0, width, height );
96   glMatrixMode( GL_PROJECTION );
97   glLoadIdentity();
98   glFrustum( -1.0 * ar, 1.0 * ar, -1.0, 1.0, 5.0, 25.0 );
99   glMatrixMode( GL_MODELVIEW );
100   glLoadIdentity();
101   glTranslatef( 0.0, 0.0, -12.0 );
102   glScalef(2, 2, 2);
103}
104
105
106static void Key( unsigned char key, int x, int y )
107{
108   (void) x;
109   (void) y;
110   switch (key) {
111      case 'a':
112         Anim = !Anim;
113         if (Anim)
114            glutIdleFunc(Idle);
115         else
116            glutIdleFunc(NULL);
117         break;
118      case 'p':
119         Phi += 0.2;
120         break;
121      case 'z':
122         Zrot -= 5.0;
123         break;
124      case 'Z':
125         Zrot += 5.0;
126         break;
127      case 27:
128         exit(0);
129         break;
130   }
131   glutPostRedisplay();
132}
133
134
135static void SpecialKey( int key, int x, int y )
136{
137   const GLfloat step = 3.0;
138   (void) x;
139   (void) y;
140   switch (key) {
141      case GLUT_KEY_UP:
142         Xrot -= step;
143         break;
144      case GLUT_KEY_DOWN:
145         Xrot += step;
146         break;
147      case GLUT_KEY_LEFT:
148         Yrot -= step;
149         break;
150      case GLUT_KEY_RIGHT:
151         Yrot += step;
152         break;
153   }
154   glutPostRedisplay();
155}
156
157
158static void Init( void )
159{
160   /*
161    * c[0..3] = modelview matrix
162    * c[4..7] = inverse modelview matrix
163    * c[30] = gravity source location
164    * c[31] = gravity source strength
165    * c[32] = light pos
166    * c[35] = diffuse color
167    */
168   static const char prog[] =
169      "!!VP1.0\n"
170
171      "# Compute distance from vertex to gravity source\n"
172      "ADD   R1, c[30], -v[OPOS]; # vector from vertex to gravity\n"
173      "DP3   R2, R1, R1;          # dot product\n"
174      "RSQ   R2, R2.x;            # square root = distance\n"
175      "MUL   R2, R2, c[31].xxxx;  # scale by the gravity factor\n"
176
177      "# Displace vertex by gravity factor along R1 vector\n"
178      "MAD   R3, R1, R2, v[OPOS];\n"
179
180      "# Continue with typical modelview/projection\n"
181      "DP4   o[HPOS].x, c[0], R3 ;	# object x MVP -> clip\n"
182      "DP4   o[HPOS].y, c[1], R3 ;\n"
183      "DP4   o[HPOS].z, c[2], R3 ;\n"
184      "DP4   o[HPOS].w, c[3], R3 ;\n"
185
186      "MOV   o[COL0], v[COL0];\n       # copy input color to output color\n"
187
188      "END";
189
190   if (!glutExtensionSupported("GL_NV_vertex_program")) {
191      printf("Sorry, this program requires GL_NV_vertex_program\n");
192      exit(1);
193   }
194
195   glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1,
196                   strlen(prog), (const GLubyte *) prog);
197   assert(glIsProgramNV(1));
198   glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1);
199
200   /* Load the program registers */
201   glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV);
202   glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV);
203
204   /* Light position */
205   glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 32, 2, 2, 4, 1);
206   /* Diffuse material color */
207   glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 35, 0.25, 0, 0.25, 1);
208
209   /* Gravity strength */
210   glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 31, .5, 0, 0, 0);
211
212   glEnable(GL_DEPTH_TEST);
213   glClearColor(0.3, 0.3, 0.3, 1);
214   glShadeModel(GL_FLAT);
215   glPointSize(3);
216   printf("glGetError = %d\n", (int) glGetError());
217}
218
219
220int main( int argc, char *argv[] )
221{
222   glutInit( &argc, argv );
223   glutInitWindowPosition( 0, 0 );
224   glutInitWindowSize( 250, 250 );
225   glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH );
226   glutCreateWindow(argv[0]);
227   glewInit();
228   glutReshapeFunc( Reshape );
229   glutKeyboardFunc( Key );
230   glutSpecialFunc( SpecialKey );
231   glutDisplayFunc( Display );
232   if (Anim)
233      glutIdleFunc(Idle);
234   Init();
235   glutMainLoop();
236   return 0;
237}
238