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