#include "VertexProgramATI.h" #include #if defined(__APPLE__) || defined(sgi) // #define GL_EXT_vertex_shader 1 // #define GL_GLEXT_FUNCTION_POINTERS 1 // #include // #include // #include #include "extensions.h" #elif defined(__linux__) #include #include #include #include "extensions.h" #else //#define DECLARE_EXTENSION_SUBSTANCE #include "extensions.h" #include "glext.h" #endif VertexProgramATI::VertexProgramATI(int iters, int w, int h, double ax, double ay, double ex, double ey) : VertexProgram(iters, w, h, ax, ay, ex, ey) { #if defined(__APPLE__) || defined(sgi) // TODO: Why the hell NSGLGetProcAddress() this return a function pointer of functions which crashes ? // VertexProgramATI is currently disabled on the Mac. if (!CheckExtension("GL_EXT_vertex_shader")) printf("Required extension (GL_EXT_vertex_shader) not supported.\n"); else printf("Required extension (GL_EXT_vertex_shader) is supported, but VertexProgram is currently disabled for Macs. Sorry.\n"); //printf("If you can tell me why OpenGL extension functions are crashing on the Mac, you'll get your VertexProgram.\n"); isValid_ = false; return; #endif isValid_ = initialize(iters, w, h, ax, ay, ex, ey); } VertexProgramATI::~VertexProgramATI(void) { if (isValid_) { #ifdef WIN32 // Uhm... check this. glDeleteVertexShaderEXT(xform_); glDisable(GL_VERTEX_SHADER_EXT); #endif } } bool VertexProgramATI::isValid(void) { return isValid_; } /** * Daniele: * Producing this code has been a real PITA (Pain In The Ass). */ bool VertexProgramATI::initialize(int iters, int w, int h, double ax, double ay, double ex, double ey) { iters_ = iters; #if defined(WIN32) bool rc = InitExtensionsATI(); if (!rc) { printf("ATI Vertex Program: Required extensions are not supported.\n"); return false; } printf("ATI Extensions initialized.\n"); glGetIntegerv(GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT, &maxInstr_); printf(" Maximum number of VP instructions: %d\n", maxInstr_); GLint maxLocalConsts = 0; glGetIntegerv(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT, &maxLocalConsts); printf(" Maximum number of VP local consts: %d\n", maxLocalConsts); GLint maxLocals = 0; glGetIntegerv(GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT , &maxLocals); printf(" Maximum number of VP locals: %d\n", maxLocals); this->prepareWorldSpace(w, h, ax, ay, ex, ey); // Bind OpenGL state data GLuint modelview; GLuint projection; GLuint vertex; modelview = glBindParameterEXT(GL_MODELVIEW_MATRIX); projection = glBindParameterEXT(GL_PROJECTION_MATRIX); vertex = glBindParameterEXT(GL_CURRENT_VERTEX_EXT); // Request 1 vertex shader xform_ = glGenVertexShadersEXT(1); // Bind shader glBindVertexShaderEXT(xform_); // Generate shader glBeginVertexShaderEXT(); { // Place constants into GPU Constant Memory //glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 0, 1.0f, -1.0f, 0.0f, 0.5f); //glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 1, 0.2f, 1.0f, 0.4f, 0.0f); //glProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, 2, 10.0f, 10.0f, 10.0f, 10.0f); float c0_data[] = {1.0f, -1.0f, 0.0f, 0.5f}; GLuint c0 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_CONSTANT_EXT, GL_FULL_RANGE_EXT, 1); glSetLocalConstantEXT(c0, GL_FLOAT, c0_data); //glSetLocalConstantEXT(c1, GL_FLOAT, c1_data); //glSetLocalConstantEXT(c2, GL_FLOAT, c2_data); // Setup local registers GLuint r0 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); GLuint r1 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); GLuint r2 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); GLuint r3 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); GLuint r4 = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); GLuint eyeVertex = glGenSymbolsEXT(GL_VECTOR_EXT, GL_LOCAL_EXT, GL_FULL_RANGE_EXT, 1); // Transform the vertex glShaderOp2EXT(GL_OP_MULTIPLY_MATRIX_EXT, eyeVertex, modelview, vertex ); glShaderOp2EXT(GL_OP_MULTIPLY_MATRIX_EXT, GL_OUTPUT_VERTEX_EXT, projection, eyeVertex ); // Init stuff //"MUL R0, v[0].xyzy, c[0].xxxy;" //"MUL R4, R0.xzyw, c[0].xxww;" glSwizzleEXT(r2, vertex, GL_X_EXT, GL_Y_EXT, GL_Z_EXT, GL_Y_EXT); glSwizzleEXT(r3, c0, GL_X_EXT, GL_X_EXT, GL_X_EXT, GL_Y_EXT); glShaderOp2EXT(GL_OP_MUL_EXT, r0, r2, r3); glSwizzleEXT(r2, r0, GL_X_EXT, GL_Z_EXT, GL_Y_EXT, GL_W_EXT); glSwizzleEXT(r3, c0, GL_X_EXT, GL_X_EXT, GL_W_EXT, GL_W_EXT); glShaderOp2EXT(GL_OP_MUL_EXT, r4, r2, r3); printf(" Generating VP. Takes a while on my ATI R9000...\n"); // Iterz for (int i=0; iprepareWorldSpace(w, h, ax, ay, ex, ey); // Enable VERTEX SHADERS glEnable(GL_VERTEX_SHADER_EXT); if (!glIsEnabled(GL_VERTEX_SHADER_EXT)) { printf("ERROR: Could not enable VERTEX SHADER extension\n"); return false; } #endif return true; } void VertexProgramATI::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(); this->setOrtho2D(ax, ex, ay+sy*(double)h, ay); } bool VertexProgramATI::setOrtho2D(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top) { gluOrtho2D(left, right, bottom, top); return true; }; bool VertexProgramATI::checkRequiredExtensions(void) { #if defined(WIN32) //if (!CheckExtensionATI("GL_ARB_multitexture")) return false; //if (!CheckExtensionATI("GL_ATI_element_array")) return false; //if (!CheckExtensionATI("GL_ATI_fragment_shader")) return false; //if (!CheckExtensionATI("GL_ATI_texture_mirror_once")) return false; //if (!CheckExtensionATI("GL_ATI_vertex_array_object")) return false; if (!CheckExtension("GL_EXT_vertex_shader")) return false; //if (!CheckExtensionATI("GL_EXT_texture3D")) return false; if (!glBeginVertexShaderEXT) return false; if (!glEndVertexShaderEXT) return false; if (!glBindVertexShaderEXT) return false; if (!glGenVertexShadersEXT) return false; if (!glDeleteVertexShaderEXT) return false; if (!glShaderOp1EXT) return false; if (!glShaderOp2EXT) return false; if (!glShaderOp3EXT) return false; if (!glSwizzleEXT) return false; if (!glWriteMaskEXT) return false; if (!glInsertComponentEXT) return false; if (!glExtractComponentEXT) return false; if (!glGenSymbolsEXT) return false; if (!glSetInvariantEXT) return false; if (!glSetLocalConstantEXT) return false; if (!glVariantbvEXT) return false; if (!glVariantsvEXT) return false; if (!glVariantivEXT) return false; if (!glVariantfvEXT) return false; if (!glVariantdvEXT) return false; if (!glVariantubvEXT) return false; if (!glVariantusvEXT) return false; if (!glVariantuivEXT) return false; if (!glVariantPointerEXT) return false; if (!glEnableVariantClientStateEXT) return false; if (!glDisableVariantClientStateEXT) return false; if (!glBindLightParameterEXT) return false; if (!glBindMaterialParameterEXT) return false; if (!glBindTexGenParameterEXT) return false; if (!glBindTextureUnitParameterEXT) return false; if (!glBindParameterEXT) return false; if (!glIsVariantEnabledEXT) return false; if (!glGetVariantBooleanvEXT) return false; if (!glGetVariantIntegervEXT) return false; if (!glGetVariantFloatvEXT) return false; if (!glGetVariantPointervEXT) return false; if (!glGetInvariantBooleanvEXT) return false; if (!glGetInvariantIntegervEXT) return false; if (!glGetInvariantFloatvEXT) return false; if (!glGetLocalConstantBooleanvEXT) return false; if (!glGetLocalConstantIntegervEXT) return false; if (!glGetLocalConstantFloatvEXT) return false; // Check ok #endif return true; }