///////////////////////////////////////////////////////////////// // 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 gltLoadShaderPairSrc(const char *szVertexSrc, const char *szFragmentSrc) { // 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. gltLoadShaderSrc(szVertexSrc, hVertexShader); gltLoadShaderSrc(szFragmentSrc, hFragmentShader); // 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 from the specified file. Returns false if the // shader could not be loaded bool gltLoadShaderFile(const char *szFile, GLuint shader) { GLint shaderLength = 0; FILE *fp; // Open the shader file fp = fopen(szFile, "r"); if(fp != NULL) { // See how long the file is while (fgetc(fp) != EOF) shaderLength++; // Allocate a block of memory to send in the shader assert(shaderLength < MAX_SHADER_LENGTH); // make me bigger! if(shaderLength > MAX_SHADER_LENGTH) { fclose(fp); return false; } // Go back to beginning of file rewind(fp); // Read the whole file in if (shaderText != NULL) fread(shaderText, 1, shaderLength, fp); // Make sure it is null terminated and close the file shaderText[shaderLength] = '\0'; fclose(fp); } else return false; // printf(shaderText); // Load the string gltLoadShaderSrc((const char *)shaderText, shader); return true; }
///////////////////////////////////////////////////////////////// // Load a pair of shaders, compile, and link together. Specify the complete // source code text for each shader. Note, there is no support for // just loading say a vertex program... you have to do both. GLuint gltLoadShaderPairSrcWithAttributes(const char *szVertexSrc, const char *szFragmentSrc, ...) { // 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. gltLoadShaderSrc(szVertexSrc, hVertexShader); gltLoadShaderSrc(szFragmentSrc, hFragmentShader); // 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); // List of attributes va_list attributeList; va_start(attributeList, szFragmentSrc); 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); 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; }
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); gltLoadShaderSrc(szVertexProg, hVertexShader); gltLoadShaderSrc(szFragmentProg, hFragmentShader); // Compile them glCompileShader(hVertexShader); GLuint err = glGetError(); assert(err==GL_NO_ERROR); glCompileShader(hFragmentShader); err = glGetError(); assert(err==GL_NO_ERROR); // 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); return 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; }
/////////////////////////////////////////////////////////////////////////////////////////////// // Load the shader from source, with the supplied named attributes GLuint GLShaderManager::LoadShaderPairSrcWithAttributes(const char *szName, const char *szVertexProg, const char *szFragmentProg, ...) { // Check for duplicate GLuint uiShader = LookupShader(szName, szName); 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. gltLoadShaderSrc(szVertexProg, hVertexShader); gltLoadShaderSrc(szFragmentProg, hFragmentShader); // 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, szFragmentProg); 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, szName, MAX_SHADER_NAME_LENGTH); strncpy_s(shaderEntry.szFragShaderName, MAX_SHADER_NAME_LENGTH, szName, MAX_SHADER_NAME_LENGTH); // shaderTable.push_back(shaderEntry); return shaderEntry.uiShaderID; }