132001f49Smrg/* 232001f49Smrg * Warp a triangle mesh with a vertex program. 332001f49Smrg */ 432001f49Smrg 532001f49Smrg#include <assert.h> 632001f49Smrg#include <string.h> 732001f49Smrg#include <stdio.h> 832001f49Smrg#include <stdlib.h> 932001f49Smrg#include <math.h> 1032001f49Smrg#include <GL/glew.h> 1132001f49Smrg#include "glut_wrap.h" 1232001f49Smrg 1332001f49Smrgstatic float Xrot = -60.0, Yrot = 0.0, Zrot = 0.0; 1432001f49Smrgstatic GLboolean Anim = GL_TRUE; 1532001f49Smrgstatic GLfloat Phi = 0.0; 1632001f49Smrg 1732001f49Smrg 1832001f49Smrgstatic void Idle( void ) 1932001f49Smrg{ 2032001f49Smrg Phi += 0.01; 2132001f49Smrg glutPostRedisplay(); 2232001f49Smrg} 2332001f49Smrg 2432001f49Smrg 2532001f49Smrgstatic void DrawMesh( int rows, int cols ) 2632001f49Smrg{ 2732001f49Smrg static const GLfloat colorA[3] = { 0, 1, 0 }; 2832001f49Smrg static const GLfloat colorB[3] = { 0, 0, 1 }; 2932001f49Smrg const float dx = 2.0 / (cols - 1); 3032001f49Smrg const float dy = 2.0 / (rows - 1); 3132001f49Smrg float x, y; 3232001f49Smrg int i, j; 3332001f49Smrg 3432001f49Smrg#if 1 3532001f49Smrg#define COLOR3FV(c) glVertexAttrib3fvNV(3, c) 3632001f49Smrg#define VERTEX2F(x, y) glVertexAttrib2fNV(0, x, y) 3732001f49Smrg#else 3832001f49Smrg#define COLOR3FV(c) glColor3fv(c) 3932001f49Smrg#define VERTEX2F(x, y) glVertex2f(x, y) 4032001f49Smrg#endif 4132001f49Smrg 4232001f49Smrg y = -1.0; 4332001f49Smrg for (i = 0; i < rows - 1; i++) { 4432001f49Smrg glBegin(GL_QUAD_STRIP); 4532001f49Smrg x = -1.0; 4632001f49Smrg for (j = 0; j < cols; j++) { 4732001f49Smrg if ((i + j) & 1) 4832001f49Smrg COLOR3FV(colorA); 4932001f49Smrg else 5032001f49Smrg COLOR3FV(colorB); 5132001f49Smrg VERTEX2F(x, y); 5232001f49Smrg VERTEX2F(x, y + dy); 5332001f49Smrg x += dx; 5432001f49Smrg } 5532001f49Smrg glEnd(); 5632001f49Smrg y += dy; 5732001f49Smrg } 5832001f49Smrg} 5932001f49Smrg 6032001f49Smrg 6132001f49Smrgstatic void Display( void ) 6232001f49Smrg{ 6332001f49Smrg glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 6432001f49Smrg 6532001f49Smrg glPushMatrix(); 6632001f49Smrg glRotatef(Xrot, 1, 0, 0); 6732001f49Smrg glRotatef(Yrot, 0, 1, 0); 6832001f49Smrg glRotatef(Zrot, 0, 0, 1); 6932001f49Smrg 7032001f49Smrg /* Position the gravity source */ 7132001f49Smrg { 7232001f49Smrg GLfloat x, y, z, r = 0.5; 7332001f49Smrg x = r * cos(Phi); 7432001f49Smrg y = r * sin(Phi); 7532001f49Smrg z = 1.0; 7632001f49Smrg glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 30, x, y, z, 1); 7732001f49Smrg glDisable(GL_VERTEX_PROGRAM_NV); 7832001f49Smrg glBegin(GL_POINTS); 7932001f49Smrg glColor3f(1,1,1); 8032001f49Smrg glVertex3f(x, y, z); 8132001f49Smrg glEnd(); 8232001f49Smrg } 8332001f49Smrg 8432001f49Smrg glEnable(GL_VERTEX_PROGRAM_NV); 8532001f49Smrg DrawMesh(8, 8); 8632001f49Smrg glPopMatrix(); 8732001f49Smrg 8832001f49Smrg glutSwapBuffers(); 8932001f49Smrg} 9032001f49Smrg 9132001f49Smrg 9232001f49Smrgstatic void Reshape( int width, int height ) 9332001f49Smrg{ 9432001f49Smrg float ar = (float) width / (float) height; 9532001f49Smrg glViewport( 0, 0, width, height ); 9632001f49Smrg glMatrixMode( GL_PROJECTION ); 9732001f49Smrg glLoadIdentity(); 9832001f49Smrg glFrustum( -1.0 * ar, 1.0 * ar, -1.0, 1.0, 5.0, 25.0 ); 9932001f49Smrg glMatrixMode( GL_MODELVIEW ); 10032001f49Smrg glLoadIdentity(); 10132001f49Smrg glTranslatef( 0.0, 0.0, -12.0 ); 10232001f49Smrg glScalef(2, 2, 2); 10332001f49Smrg} 10432001f49Smrg 10532001f49Smrg 10632001f49Smrgstatic void Key( unsigned char key, int x, int y ) 10732001f49Smrg{ 10832001f49Smrg (void) x; 10932001f49Smrg (void) y; 11032001f49Smrg switch (key) { 11132001f49Smrg case 'a': 11232001f49Smrg Anim = !Anim; 11332001f49Smrg if (Anim) 11432001f49Smrg glutIdleFunc(Idle); 11532001f49Smrg else 11632001f49Smrg glutIdleFunc(NULL); 11732001f49Smrg break; 11832001f49Smrg case 'p': 11932001f49Smrg Phi += 0.2; 12032001f49Smrg break; 12132001f49Smrg case 'z': 12232001f49Smrg Zrot -= 5.0; 12332001f49Smrg break; 12432001f49Smrg case 'Z': 12532001f49Smrg Zrot += 5.0; 12632001f49Smrg break; 12732001f49Smrg case 27: 12832001f49Smrg exit(0); 12932001f49Smrg break; 13032001f49Smrg } 13132001f49Smrg glutPostRedisplay(); 13232001f49Smrg} 13332001f49Smrg 13432001f49Smrg 13532001f49Smrgstatic void SpecialKey( int key, int x, int y ) 13632001f49Smrg{ 13732001f49Smrg const GLfloat step = 3.0; 13832001f49Smrg (void) x; 13932001f49Smrg (void) y; 14032001f49Smrg switch (key) { 14132001f49Smrg case GLUT_KEY_UP: 14232001f49Smrg Xrot -= step; 14332001f49Smrg break; 14432001f49Smrg case GLUT_KEY_DOWN: 14532001f49Smrg Xrot += step; 14632001f49Smrg break; 14732001f49Smrg case GLUT_KEY_LEFT: 14832001f49Smrg Yrot -= step; 14932001f49Smrg break; 15032001f49Smrg case GLUT_KEY_RIGHT: 15132001f49Smrg Yrot += step; 15232001f49Smrg break; 15332001f49Smrg } 15432001f49Smrg glutPostRedisplay(); 15532001f49Smrg} 15632001f49Smrg 15732001f49Smrg 15832001f49Smrgstatic void Init( void ) 15932001f49Smrg{ 16032001f49Smrg /* 16132001f49Smrg * c[0..3] = modelview matrix 16232001f49Smrg * c[4..7] = inverse modelview matrix 16332001f49Smrg * c[30] = gravity source location 16432001f49Smrg * c[31] = gravity source strength 16532001f49Smrg * c[32] = light pos 16632001f49Smrg * c[35] = diffuse color 16732001f49Smrg */ 16832001f49Smrg static const char prog[] = 16932001f49Smrg "!!VP1.0\n" 17032001f49Smrg 17132001f49Smrg "# Compute distance from vertex to gravity source\n" 17232001f49Smrg "ADD R1, c[30], -v[OPOS]; # vector from vertex to gravity\n" 17332001f49Smrg "DP3 R2, R1, R1; # dot product\n" 17432001f49Smrg "RSQ R2, R2.x; # square root = distance\n" 17532001f49Smrg "MUL R2, R2, c[31].xxxx; # scale by the gravity factor\n" 17632001f49Smrg 17732001f49Smrg "# Displace vertex by gravity factor along R1 vector\n" 17832001f49Smrg "MAD R3, R1, R2, v[OPOS];\n" 17932001f49Smrg 18032001f49Smrg "# Continue with typical modelview/projection\n" 18132001f49Smrg "DP4 o[HPOS].x, c[0], R3 ; # object x MVP -> clip\n" 18232001f49Smrg "DP4 o[HPOS].y, c[1], R3 ;\n" 18332001f49Smrg "DP4 o[HPOS].z, c[2], R3 ;\n" 18432001f49Smrg "DP4 o[HPOS].w, c[3], R3 ;\n" 18532001f49Smrg 18632001f49Smrg "MOV o[COL0], v[COL0];\n # copy input color to output color\n" 18732001f49Smrg 18832001f49Smrg "END"; 18932001f49Smrg 19032001f49Smrg if (!glutExtensionSupported("GL_NV_vertex_program")) { 19132001f49Smrg printf("Sorry, this program requires GL_NV_vertex_program\n"); 19232001f49Smrg exit(1); 19332001f49Smrg } 19432001f49Smrg 19532001f49Smrg glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1, 19632001f49Smrg strlen(prog), (const GLubyte *) prog); 19732001f49Smrg assert(glIsProgramNV(1)); 19832001f49Smrg glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1); 19932001f49Smrg 20032001f49Smrg /* Load the program registers */ 20132001f49Smrg glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); 20232001f49Smrg glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV); 20332001f49Smrg 20432001f49Smrg /* Light position */ 20532001f49Smrg glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 32, 2, 2, 4, 1); 20632001f49Smrg /* Diffuse material color */ 20732001f49Smrg glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 35, 0.25, 0, 0.25, 1); 20832001f49Smrg 20932001f49Smrg /* Gravity strength */ 21032001f49Smrg glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 31, .5, 0, 0, 0); 21132001f49Smrg 21232001f49Smrg glEnable(GL_DEPTH_TEST); 21332001f49Smrg glClearColor(0.3, 0.3, 0.3, 1); 21432001f49Smrg glShadeModel(GL_FLAT); 21532001f49Smrg glPointSize(3); 21632001f49Smrg printf("glGetError = %d\n", (int) glGetError()); 21732001f49Smrg} 21832001f49Smrg 21932001f49Smrg 22032001f49Smrgint main( int argc, char *argv[] ) 22132001f49Smrg{ 22232001f49Smrg glutInit( &argc, argv ); 22332001f49Smrg glutInitWindowPosition( 0, 0 ); 22432001f49Smrg glutInitWindowSize( 250, 250 ); 22532001f49Smrg glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH ); 22632001f49Smrg glutCreateWindow(argv[0]); 22732001f49Smrg glewInit(); 22832001f49Smrg glutReshapeFunc( Reshape ); 22932001f49Smrg glutKeyboardFunc( Key ); 23032001f49Smrg glutSpecialFunc( SpecialKey ); 23132001f49Smrg glutDisplayFunc( Display ); 23232001f49Smrg if (Anim) 23332001f49Smrg glutIdleFunc(Idle); 23432001f49Smrg Init(); 23532001f49Smrg glutMainLoop(); 23632001f49Smrg return 0; 23732001f49Smrg} 238