bool ShaderProgram::build() { m_needsBuild = false; m_generation = s_validGeneration; // Inject source blocks std::string vertSrc = m_vertexShaderSource; std::string fragSrc = m_fragmentShaderSource; applySourceBlocks(vertSrc, fragSrc); // Try to compile vertex and fragment shaders, releasing resources and quiting on failure GLint vertexShader = makeCompiledShader(vertSrc, GL_VERTEX_SHADER); if (vertexShader == 0) { return false; } GLint fragmentShader = makeCompiledShader(fragSrc, GL_FRAGMENT_SHADER); if (fragmentShader == 0) { glDeleteShader(vertexShader); return false; } // Try to link shaders into a program, releasing resources and quiting on failure GLint program = makeLinkedShaderProgram(fragmentShader, vertexShader); if (program == 0) { glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return false; } // New shaders linked successfully, so replace old shaders and program if (m_glProgram == s_activeGlProgram) { glUseProgram(0); s_activeGlProgram = 0; } // Delete handles for old shaders and program; values of 0 are silently ignored glDeleteShader(m_glFragmentShader); glDeleteShader(m_glVertexShader); glDeleteProgram(m_glProgram); m_glFragmentShader = fragmentShader; m_glVertexShader = vertexShader; m_glProgram = program; // Clear any cached shader locations m_attribMap.clear(); m_uniformMap.clear(); return true; }
bool ShaderProgram::buildFromSourceStrings(const std::string& _fragSrc, const std::string& _vertSrc) { std::string glslHeader = "#ifdef GL_ES\nprecision mediump float;\n#endif\n\n"; std::string vertSrc = glslHeader + _vertSrc; std::string fragSrc = glslHeader + _fragSrc; // Try to compile vertex and fragment shaders, releasing resources and quiting on failure GLint vertexShader = makeCompiledShader(vertSrc, GL_VERTEX_SHADER); if (vertexShader == 0) { return false; } GLint fragmentShader = makeCompiledShader(fragSrc, GL_FRAGMENT_SHADER); if (fragmentShader == 0) { glDeleteShader(vertexShader); return false; } // Try to link shaders into a program, releasing resources and quiting on failure GLint program = makeLinkedShaderProgram(fragmentShader, vertexShader); if (program == 0) { glDeleteShader(vertexShader); glDeleteShader(fragmentShader); return false; } // New shaders linked successfully, so replace old shaders and program if (m_glProgram == s_activeGlProgram) { glUseProgram(0); s_activeGlProgram = 0; } glDeleteShader(m_glFragmentShader); glDeleteShader(m_glVertexShader); glDeleteProgram(m_glProgram); m_glFragmentShader = fragmentShader; m_glVertexShader = vertexShader; m_glProgram = program; // Make copies of the shader source code inputs, for this program to keep m_fragmentShaderSource = std::string(_fragSrc); m_vertexShaderSource = std::string(_vertSrc); // Clear any cached shader locations m_attribMap.clear(); m_uniformMap.clear(); return true; }