#include "VertexProgramNV.h" #include #include #include "vpext.h" // GPU Vertex Program - Based on algo by Erik Lindholm (nVidia) ------------------- GLuint vpid_; // Vertex Program id const unsigned char vertexProgram0_[] = { // Standard vertex program header "!!VP1.0\n" // Transform stuff "DP4 o[HPOS].x, c[4], v[OPOS];" "DP4 o[HPOS].y, c[5], v[OPOS];" "DP4 o[HPOS].z, c[6], v[OPOS];" "DP4 o[HPOS].w, c[7], v[OPOS];" // Init stuff "MUL R0, v[0].xyzy, c[0].xxxy;" "MUL R4, R0.xzyw, c[0].xxww;" }; const unsigned char vertexProgram1_[] = { "MAD R1, R0.xyxx, R0.xyyw, R4;" "ADD R0.xyw, R1.xzww, -R1.ywwz;" }; const unsigned char vertexProgram2_[] = { "MOV o[COL0].xyz, R1.xyzw;" "END" }; unsigned char vertexProgram_[sizeof(vertexProgram0_) + sizeof(vertexProgram1_)*128000 + sizeof(vertexProgram2_)]; VertexProgramNV::VertexProgramNV(int iters, int w, int h, double ax, double ay, double ex, double ey) : VertexProgram(iters, w, h, ax, ay, ex, ey) { isValid_ = initialize(iters, w, h, ax, ay, ex, ey); } VertexProgramNV::~VertexProgramNV(void) { #if !defined(sgi) if (isValid_) glDisable(GL_VERTEX_PROGRAM_NV); #endif } bool VertexProgramNV::isValid(void) { return isValid_; } bool VertexProgramNV::initialize(int iters, int w, int h, double ax, double ay, double ex, double ey) { return initializeGPU_VP(iters, w, h, ax, ay, ex, ey); } bool VertexProgramNV::initializeGPU_VP(int iters, int w, int h, double ax, double ay, double ex, double ey) { #if defined(sgi) return false; #else //Initialize NV_Vertex_Program if (!InitializeVertexProgramNV()) { return false; } else { // Generate Vertex Program for required number of iters char* vpPrt = (char*) vertexProgram_; int len = sprintf(vpPrt, "%s", vertexProgram0_); vpPrt += len; for (unsigned int i=0; iprepareWorldSpace(w, h, ax, ay, ex, ey); // Enable Vertex Programs glEnable(GL_VERTEX_PROGRAM_NV); } return true; #endif // sgi } void VertexProgramNV::prepareWorldSpace(int w, int h, double ax, double ay, double ex, double ey) { // Recalc real plane parameters double sx = (ex - ax) / ((double) w); //sy_ = (ey_ - ay_) / ((double) h_); double sy = sx; glMatrixMode(GL_PROJECTION); glLoadIdentity(); setOrtho2D(ax, ex, ay+sy*(double)h, ay); } bool VertexProgramNV::setOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) { gluOrtho2D(left, right, bottom, top); #if defined(sgi) return false; #else glTrackMatrixNV(GL_VERTEX_PROGRAM_NV, 4, GL_PROJECTION, GL_IDENTITY_NV); #endif return true; }; bool VertexProgramNV::checkRequiredExtensions(void) { // TODO return true; }