void glCompileShaderFromFile(GLhandleARB shaderObject,const char* shaderSourceFileName) { /* Open the source file: */ IO::FilePtr shaderSourceFile(IO::openFile(shaderSourceFileName)); /* Compile the shader from the source file: */ glCompileShaderFromFile(shaderObject,shaderSourceFileName,*shaderSourceFile); }
const GLuint render::ShaderFactory::getShader(const std::string shaderName, GLenum shaderType) { //Check for shader in flyweight pool if(shaders.find(shaderName) != shaders.end()) { return shaders[shaderName]; } //Shader not in flyweight pool: load and compile shader std::ifstream shaderSourceFile(std::string("./shaders/" + shaderName + ".glsl").c_str()); if(!shaderSourceFile.is_open()) { //TODO To logging std::cerr << "Could not find shader " << shaderName << std::endl; assert(shaderSourceFile.is_open()); } std::stringstream shaderSourceStream; while(shaderSourceFile.good()) { std::string line; std::getline(shaderSourceFile, line); shaderSourceStream << line << std::endl; } //We need to copy the C-string because of the volatile characteristics of std::string.c_str() char* shaderSourceCString = new char[shaderSourceStream.str().size()+1]; std::strcpy(shaderSourceCString, shaderSourceStream.str().c_str()); GLuint shader = glCreateShader(shaderType); glShaderSource(shader, 1, (const GLchar**) &shaderSourceCString, 0); glCompileShader(shader); checkShaderError(shader); delete[] shaderSourceCString; shaders.insert(std::pair<std::string, GLuint>(shaderName, shader)); return shader; }
void GLShader::loadShader(GLhandleARB shaderObject,const char* shaderSourceFileName) { /* Open the source file: */ Misc::File shaderSourceFile(shaderSourceFileName,"rt"); /* Determine the length of the source file: */ shaderSourceFile.seekEnd(0); GLint shaderSourceLength=GLint(shaderSourceFile.tell()); shaderSourceFile.seekSet(0); /* Read the shader source: */ GLcharARB* shaderSource=new GLcharARB[shaderSourceLength]; shaderSourceFile.read<GLcharARB>(shaderSource,shaderSourceLength); /* Upload the shader source into the shader object: */ const GLcharARB* ss=shaderSource; glShaderSourceARB(shaderObject,1,&ss,&shaderSourceLength); delete[] shaderSource; /* Compile the shader source: */ glCompileShaderARB(shaderObject); /* Check if the shader compiled successfully: */ GLint compileStatus; glGetObjectParameterivARB(shaderObject,GL_OBJECT_COMPILE_STATUS_ARB,&compileStatus); if(!compileStatus) { /* Get some more detailed information: */ GLcharARB compileLogBuffer[2048]; GLsizei compileLogSize; glGetInfoLogARB(shaderObject,sizeof(compileLogBuffer),&compileLogSize,compileLogBuffer); /* Signal an error: */ Misc::throwStdErr("%s",compileLogBuffer); } }
/****************************************************************************** * Loads and compiles a GLSL shader and adds it to the given program object. ******************************************************************************/ void ViewportSceneRenderer::loadShader(QOpenGLShaderProgram* program, QOpenGLShader::ShaderType shaderType, const QString& filename) { // Load shader source. QFile shaderSourceFile(filename); if(!shaderSourceFile.open(QFile::ReadOnly)) throw Exception(QString("Unable to open shader source file %1.").arg(filename)); QByteArray shaderSource; // Insert GLSL version string at the top. // Pick GLSL language version based on current OpenGL version. if((glformat().majorVersion() >= 3 && glformat().minorVersion() >= 2) || glformat().majorVersion() > 3) shaderSource.append("#version 150\n"); else if(glformat().majorVersion() >= 3) shaderSource.append("#version 130\n"); else shaderSource.append("#version 120\n"); // Preprocess shader source while reading it from the file. // // This is a workaround for some older OpenGL driver, which do not perform the // preprocessing of shader source files correctly (probably the __VERSION__ macro is not working). // // Here, in our own simple preprocessor implementation, we only handle // #if __VERSION__ >= 130 // ... // #else // ... // #endif // statements, which are used by most shaders to discriminate core and compatibility profiles. bool isFiltered = false; int ifstack = 0; int filterstackpos = 0; while(!shaderSourceFile.atEnd()) { QByteArray line = shaderSourceFile.readLine(); if(line.contains("__VERSION__") && line.contains("130")) { OVITO_ASSERT(line.contains("#if")); OVITO_ASSERT(!isFiltered); if(line.contains(">=") && glformat().majorVersion() < 3) isFiltered = true; if(line.contains("<") && glformat().majorVersion() >= 3) isFiltered = true; filterstackpos = ifstack; continue; } else if(line.contains("#if")) { ifstack++; } else if(line.contains("#else")) { if(ifstack == filterstackpos) { isFiltered = !isFiltered; continue; } } else if(line.contains("#endif")) { if(ifstack == filterstackpos) { filterstackpos = -1; isFiltered = false; continue; } ifstack--; } if(!isFiltered) { shaderSource.append(line); } } // Load and compile vertex shader source. if(!program->addShaderFromSourceCode(shaderType, shaderSource)) { Exception ex(QString("The shader source file %1 failed to compile.").arg(filename)); ex.appendDetailMessage(program->log()); ex.appendDetailMessage(QStringLiteral("Problematic shader source:")); ex.appendDetailMessage(shaderSource); throw ex; } }