static void Test2( void ) { static const GLfloat p[4] = {9, 8, 7, 6}; GLfloat q[4]; /* test swizzling */ static const char *prog = "!!VSP1.0\n" "MOV R0, c[0].wzyx;\n" "MOV R1, c[1].wzyx;\n" "ADD c[2], R0, R1;\n" "END\n"; glLoadProgramNV(GL_VERTEX_STATE_PROGRAM_NV, 1, strlen(prog), (const GLubyte *) prog); assert(glIsProgramNV(1)); glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 0, 1, 2, 3, 4); glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 1, 10, 20, 30, 40); glExecuteProgramNV(GL_VERTEX_STATE_PROGRAM_NV, 1, p); glGetProgramParameterfvNV(GL_VERTEX_PROGRAM_NV, 2, GL_PROGRAM_PARAMETER_NV, q); printf("Result c[2] = %g %g %g %g (should be 44 33 22 11)\n", q[0], q[1], q[2], q[3]); }
static void Init( void ) { /* borrowed from an nvidia demo: * c[0..3] = modelview matrix * c[4..7] = inverse modelview matrix * c[32] = light pos * c[35] = diffuse color */ static const char prog[] = "!!VP1.0\n" "#Simple transform and diffuse lighting\n" "\n" "DP4 o[HPOS].x, c[0], v[OPOS] ; # object x MVP -> clip\n" "DP4 o[HPOS].y, c[1], v[OPOS] ;\n" "DP4 o[HPOS].z, c[2], v[OPOS] ;\n" "DP4 o[HPOS].w, c[3], v[OPOS] ;\n" "DP3 R1.x, c[4], v[NRML] ; # normal x MV-1T -> lighting normal\n" "DP3 R1.y, c[5], v[NRML] ;\n" "DP3 R1.z, c[6], v[NRML] ;\n" "DP3 R0, c[32], R1 ; # L.N\n" "MUL o[COL0].xyz, R0, c[35] ; # col = L.N * diffuse\n" "MOV o[TEX0], v[TEX0];\n" "END"; if (!glutExtensionSupported("GL_NV_vertex_program")) { printf("Sorry, this program requires GL_NV_vertex_program"); exit(1); } glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1, strlen(prog), (const GLubyte *) prog); assert(glIsProgramNV(1)); glBindProgramNV(GL_VERTEX_PROGRAM_NV, 1); /* Load the program registers */ glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV); /* Light position */ glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 32, 2, 2, 4, 1); /* Diffuse material color */ glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 35, 0.25, 0, 0.25, 1); glEnable(GL_VERTEX_PROGRAM_NV); glEnable(GL_DEPTH_TEST); glClearColor(0.3, 0.3, 0.3, 1); printf("glGetError = %d\n", (int) glGetError()); }
static void Test3( void ) { static const GLfloat p[4] = {0, 0, 0, 0}; GLfloat q[4]; /* normalize vector */ static const char *prog = "!!VSP1.0\n" "# c[0] = (nx,ny,nz)\n" "# R0.xyz = normalize(R1)\n" "# R0.w = 1/sqrt(nx*nx + ny*ny + nz*nz)\n" "# c[2] = R0\n" "DP3 R0.w, c[0], c[0];\n" "RSQ R0.w, R0.w;\n" "MUL R0.xyz, c[0], R0.w;\n" "MOV c[2], R0;\n" "END\n"; glLoadProgramNV(GL_VERTEX_STATE_PROGRAM_NV, 1, strlen(prog), (const GLubyte *) prog); assert(glIsProgramNV(1)); glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 0, 0, 10, 0, 0); glExecuteProgramNV(GL_VERTEX_STATE_PROGRAM_NV, 1, p); glGetProgramParameterfvNV(GL_VERTEX_PROGRAM_NV, 2, GL_PROGRAM_PARAMETER_NV, q); printf("Result c[2] = %g %g %g %g (should be 0, 1, 0, 0.1)\n", q[0], q[1], q[2], q[3]); }
//Set up openGL bool GLInit() { //set viewport int height; if (window.height==0) height=1; else height=window.height; glViewport(0, 0, window.width, height); //reset viewport //set up projection matrix glMatrixMode(GL_PROJECTION); //select projection matrix glLoadIdentity(); //reset gluPerspective(45.0f, (GLfloat)window.width/(GLfloat)height, 0.1f, 100.0f); //load identity modelview glMatrixMode(GL_MODELVIEW); glLoadIdentity(); //other states //shading glShadeModel(GL_SMOOTH); glClearColor( backgroundColor.r, backgroundColor.g, backgroundColor.b, backgroundColor.a); glColor4f(1.0f, 1.0f, 1.0f, 1.0f); //depth glClearDepth(1.0f); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); //hints glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //load vertex programs glGenProgramsNV(1, &chromaticSingleVP); glBindProgramNV(GL_VERTEX_PROGRAM_NV, chromaticSingleVP); LoadNV_vertex_program("chromatic single vp.txt", chromaticSingleVP); glGenProgramsNV(1, &simpleSingleVP); glBindProgramNV(GL_VERTEX_PROGRAM_NV, simpleSingleVP); LoadNV_vertex_program("simple single vp.txt", simpleSingleVP); glGenProgramsNV(1, &chromaticTwin1VP); glBindProgramNV(GL_VERTEX_PROGRAM_NV, chromaticTwin1VP); LoadNV_vertex_program("chromatic twin 1 vp.txt", chromaticTwin1VP); glGenProgramsNV(1, &chromaticTwin2VP); glBindProgramNV(GL_VERTEX_PROGRAM_NV, chromaticTwin2VP); LoadNV_vertex_program("chromatic twin 2 vp.txt", chromaticTwin2VP); //Set track matrices glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 0, GL_MODELVIEW_PROJECTION_NV, GL_IDENTITY_NV); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_MODELVIEW, GL_IDENTITY_NV); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 8, GL_MODELVIEW, GL_INVERSE_TRANSPOSE_NV); glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 12, GL_TEXTURE, GL_IDENTITY_NV); //Send fresnel multipication factor to c[28] glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 28, fresnel, fresnel, fresnel, 1.0f); //Send refractive indices to c[32], c[33], c[34] glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 32, index, index*index, 0.0f, 1.0f); glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 33, index+indexDelta, (index+indexDelta)*(index+indexDelta), 0.0f, 1.0f); glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 34, index+2*indexDelta, (index+2*indexDelta)*(index+2*indexDelta), 0.0f, 1.0f); //Send useful constants to c[64] glProgramParameter4fNV( GL_VERTEX_PROGRAM_NV, 64, 0.0f, 1.0f, 2.0f, 0.5f); //Init states to begin if(renderPath==CHROMATIC_SINGLE) InitChromaticSingleStates(); if(renderPath==SIMPLE_SINGLE) InitSimpleSingleStates(); return true; }
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_NVVertexProgram_nglProgramParameter4fNV(JNIEnv *env, jclass clazz, jint target, jint index, jfloat x, jfloat y, jfloat z, jfloat w, jlong function_pointer) { glProgramParameter4fNVPROC glProgramParameter4fNV = (glProgramParameter4fNVPROC)((intptr_t)function_pointer); glProgramParameter4fNV(target, index, x, y, z, w); }
//Render a frame void RenderFrame(double currentTime, double timePassed) { //Clear buffers glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //reset modelview matrix glColor4f(1.0f, 1.0f, 1.0f, 1.0f); gluLookAt( 0.0f, 1.8f, 1.8f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0); //Enable texture glBindTexture(GL_TEXTURE_2D, floorTexture); glEnable(GL_TEXTURE_2D); //Set up vertex arrays glVertexPointer(3, GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].position); glEnableClientState(GL_VERTEX_ARRAY); glNormalPointer(GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].normal); glEnableClientState(GL_NORMAL_ARRAY); glTexCoordPointer(2, GL_FLOAT, sizeof(SIMPLE_VERTEX), &vertices[0].texCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); //Use Fixed Function Pipeline if(useFixedFunction) { //Set parameters for GL lighting glLightModelfv(GL_LIGHT_MODEL_AMBIENT, white*0.1f); //global ambient glMaterialfv(GL_FRONT, GL_AMBIENT, white); glMaterialfv(GL_FRONT, GL_DIFFUSE, white); glEnable(GL_LIGHTING); //8 passes, dealing with 8 lights at a time, except final pass where we do 4 for(int i=0; i<8; ++i) { int numLightsThisPass=8; if(i==7) numLightsThisPass=4; //Set up lights for(int j=0; j<numLightsThisPass; ++j) { glLightfv(GL_LIGHT0+j, GL_POSITION, VECTOR4D(lights[i*8+j].position)); glLightfv(GL_LIGHT0+j, GL_DIFFUSE, lights[i*8+j].color); glEnable(GL_LIGHT0+j); } //If this is the final pass, disable lights 4-7 if(i==7) for(int j=4; j<7; ++j) glDisable(GL_LIGHT0+j); //Enable additive blend for all passes except the first if(i!=0) { glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); //if this is not the first pass, no ambient glLightModelfv(GL_LIGHT_MODEL_AMBIENT, black); } //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); } //Disable lights for(int j=0; j<7; ++j) glDisable(GL_LIGHT0+j); glDisable(GL_LIGHTING); glDisable(GL_BLEND); } //Use vp1 if(useVP1) { //Bind program glBindProgramNV(GL_VERTEX_PROGRAM_NV, vp1); glEnable(GL_VERTEX_PROGRAM_NV); //3 passes, dealing with 20 lights at a time for(int i=0; i<3; ++i) { //Send ambient brightness as c[4] //Only send this for the first pass if(i==0) glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, white*0.1f); else glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, black); //Update program parameters 5&6 for light0, 7&8 for light1, etc for(int j=0; j<20; ++j) { glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+5, VECTOR4D(lights[i*20+j].position)); glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+6, lights[i*20+j].color); } //Enable additive blend for passes except the first if(i>0) { glBlendFunc(GL_ONE, GL_ONE); glEnable(GL_BLEND); } //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); } glDisable(GL_VERTEX_PROGRAM_NV); glDisable(GL_BLEND); } //Use vp2 if(useVP2) { //Bind program glBindProgramNV(GL_VERTEX_PROGRAM_NV, vp2); glEnable(GL_VERTEX_PROGRAM_NV); //Send ambient brightness as c[4] glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 4, white*0.1f); //Update program parameters 5&6 for light0, 7&8 for light1, etc for(int j=0; j<60; ++j) { glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+5, VECTOR4D(lights[j].position)); glProgramParameter4fvNV(GL_VERTEX_PROGRAM_NV, 2*j+6, lights[j].color); } //Send loop parameters to c[125] glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 125, 60.0, //number of lights 5.0, //base offset of light data -1.0, 2.0);//num parameters between lights //Draw grid as triangle strips for(int j=0; j<gridDensity-1; ++j) glDrawElements( GL_TRIANGLE_STRIP, gridDensity*2, GL_UNSIGNED_INT, &indices[j*gridDensity*2]); glDisable(GL_VERTEX_PROGRAM_NV); } //reset states glDisable(GL_TEXTURE_2D); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); fpsCounter.Update(); //Print text font.StartTextMode(); glColor4f(0.0f, 1.0f, 0.0f, 1.0f); font.Print(0, 28, "FPS: %.2f", fpsCounter.GetFps()); glColor4f(1.0f, 0.0f, 0.0f, 0.0f); if(useVP1) font.Print(0, 48, "Using NV_vertex_program"); if(useVP2) font.Print(0, 48, "Using NV_vertex_program2"); if(useFixedFunction) font.Print(0, 48, "Using Fixed Function Pipeline"); font.EndTextMode(); WINDOW::Instance()->SwapBuffers(); //Save a screenshot if(WINDOW::Instance()->IsKeyPressed(VK_F1)) { WINDOW::Instance()->SaveScreenshot(); WINDOW::Instance()->SetKeyReleased(VK_F1); } //Check for an openGL error WINDOW::Instance()->CheckGLError(); //quit if necessary if(WINDOW::Instance()->IsKeyPressed(VK_ESCAPE)) PostQuitMessage(0); }