///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // file path for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. If fail clean up and return null if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Link them - assuming it works... hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(hReturn); return (GLuint)NULL; } return hReturn; }
/////////////////////////////////////////////////////////////////////////////////////////////// // Load the shader file, with the supplied named attributes GLuint GLShaderManager::LoadShaderPairWithAttributes(const char *szVertexProgFileName, const char *szFragmentProgFileName, ...) { // Check for duplicate GLuint uiShader = LookupShader(szVertexProgFileName, szFragmentProgFileName); if(uiShader != 0) return uiShader; SHADERLOOKUPETRY shaderEntry; // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. If fail clean up and return null if(gltLoadShaderFile(szVertexProgFileName, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return 0; } if(gltLoadShaderFile(szFragmentProgFileName, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return 0; } // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return 0; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return 0; } // Link them - assuming it works... shaderEntry.uiShaderID = glCreateProgram(); glAttachShader(shaderEntry.uiShaderID, hVertexShader); glAttachShader(shaderEntry.uiShaderID, hFragmentShader); // List of attributes va_list attributeList; va_start(attributeList, szFragmentProgFileName); char *szNextArg; int iArgCount = va_arg(attributeList, int); // Number of attributes for(int i = 0; i < iArgCount; i++) { int index = va_arg(attributeList, int); szNextArg = va_arg(attributeList, char*); glBindAttribLocation(shaderEntry.uiShaderID, index, szNextArg); } va_end(attributeList); glLinkProgram(shaderEntry.uiShaderID); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(shaderEntry.uiShaderID, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(shaderEntry.uiShaderID); return 0; } // Add it... strncpy_s(shaderEntry.szVertexShaderName, MAX_SHADER_NAME_LENGTH, szVertexProgFileName, MAX_SHADER_NAME_LENGTH); strncpy_s(shaderEntry.szFragShaderName, MAX_SHADER_NAME_LENGTH, szFragmentProgFileName, MAX_SHADER_NAME_LENGTH); // shaderTable.push_back(shaderEntry); return shaderEntry.uiShaderID; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // source text for each shader. After the shader names, specify the number // of attributes, followed by the index and attribute name of each attribute GLuint gltLoadShaderPairWithAttributes(const char *szVertexProg, const char *szFragmentProg, ...) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); // Load them. If fail clean up and return null // Vertex Program if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr, "The shader at %s could ot be found.\n", szVertexProg); return (GLuint)NULL; } // Fragment Program if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); fprintf(stderr,"The shader at %s could not be found.\n", szFragmentProg); return (GLuint)NULL; } // Compile them both glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors in vertex shader glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hVertexShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szVertexProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Check for errors in fragment shader glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetShaderInfoLog(hFragmentShader, 1024, NULL, infoLog); fprintf(stderr, "The shader at %s failed to compile with the following error:\n%s\n", szFragmentProg, infoLog); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Create the final program object, and attach the shaders hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); // Now, we need to bind the attribute names to their specific locations // List of attributes va_list attributeList; va_start(attributeList, szFragmentProg); // Iterate over this argument list char *szNextArg; int iArgCount = va_arg(attributeList, int); // Number of attributes for(int i = 0; i < iArgCount; i++) { int index = va_arg(attributeList, int); szNextArg = va_arg(attributeList, char*); glBindAttribLocation(hReturn, index, szNextArg); } va_end(attributeList); // Attempt to link glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { char infoLog[1024]; glGetProgramInfoLog(hReturn, 1024, NULL, infoLog); fprintf(stderr,"The programs %s and %s failed to link with the following errors:\n%s\n", szVertexProg, szFragmentProg, infoLog); glDeleteProgram(hReturn); return (GLuint)NULL; } // All done, return our ready to use shader program return hReturn; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // file path for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPair(const char *szVertexProg, const char *szFragmentProg, bool loadFromFile) { // Temporary Shader objects GLuint hVertexShader; GLuint hFragmentShader; GLuint hReturn = 0; GLint testVal; // Create shader objects hVertexShader = glCreateShader(GL_VERTEX_SHADER); hFragmentShader = glCreateShader(GL_FRAGMENT_SHADER); if (loadFromFile) { if(gltLoadShaderFile(szVertexProg, hVertexShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } if(gltLoadShaderFile(szFragmentProg, hFragmentShader) == false) { glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } } else { gltLoadShaderSrc(vertexShader, hVertexShader); gltLoadShaderSrc(fragmentShader, hFragmentShader); } // Compile them glCompileShader(hVertexShader); glCompileShader(hFragmentShader); // Check for errors glGetShaderiv(hVertexShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char temp[256] = ""; glGetShaderInfoLog( hVertexShader, 256, NULL, temp); fprintf( stderr, "Compile failed:\n%s\n", temp); assert(0); exit(0); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } glGetShaderiv(hFragmentShader, GL_COMPILE_STATUS, &testVal); if(testVal == GL_FALSE) { char temp[256] = ""; glGetShaderInfoLog( hFragmentShader, 256, NULL, temp); fprintf( stderr, "Compile failed:\n%s\n", temp); assert(0); exit(0); glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); return (GLuint)NULL; } // Link them - assuming it works... hReturn = glCreateProgram(); glAttachShader(hReturn, hVertexShader); glAttachShader(hReturn, hFragmentShader); glLinkProgram(hReturn); // These are no longer needed glDeleteShader(hVertexShader); glDeleteShader(hFragmentShader); // Make sure link worked too glGetProgramiv(hReturn, GL_LINK_STATUS, &testVal); if(testVal == GL_FALSE) { glDeleteProgram(hReturn); return (GLuint)NULL; } return hReturn; }