bool GLProgram::load(std::string vshPath,std::string fshPath){ if(!create())return false; if(!m_Vsh.load(GL_VERTEX_SHADER,vshPath)){ release(); return false; } if(!m_Fsh.load(GL_FRAGMENT_SHADER,fshPath)){ release(); return false; } attachShader(m_Vsh); attachShader(m_Fsh); onPreLink(); if(!link()){ release(); return false; } onPostLink(); detachShader(m_Vsh); detachShader(m_Fsh); m_Vsh.release(); m_Fsh.release(); return true; }
void gl::Program::detachAllShaders() { while (!shaders_.empty()) { detachShader(*shaders_.begin()); } }
void ShaderProgram::detachShadersByType(Shader::ShaderType type) { for (std::list<Shader*>::iterator iter = shaders.begin(); iter != shaders.end(); ++iter) { if ((*iter)->getType() == type) detachShader(*iter); delete (*iter); } linked = false; }
kit::Program * kit::Model::getShadowProgram(bool skinned, bool opacityMapped, bool instanced) { kit::Model::ShadowProgramFlags flags; flags.skinned = skinned; flags.opacityMapped = opacityMapped; flags.instanced = instanced; if(m_shadowPrograms.find(flags) != m_shadowPrograms.end()) { return m_shadowPrograms.at(flags); } std::cout << "Generating shadow program for flags " << (skinned? "S":"-") << (opacityMapped? "O":"-") << (instanced? "I":"-") << std::endl; // Create a program and shaders auto newProgram = new kit::Program(); // Vertex shader std::stringstream vertexSource; auto vertexShader = new kit::Shader(Shader::Type::Vertex); { vertexSource << "#version 430 core" << std::endl; vertexSource << "layout(location = 0) in vec3 in_vertexPos;" << std::endl; vertexSource << "layout(location = 1) in vec2 in_uv;" << std::endl; vertexSource << "layout(location = 4) in ivec4 in_boneids;" << std::endl; vertexSource << "layout(location = 5) in vec4 in_boneweights;" << std::endl; vertexSource << "layout(location = 0) out vec2 out_uv;" << std::endl; vertexSource << "uniform mat4 uniform_mvpMatrix;" << std::endl; if(skinned) { vertexSource << "uniform mat4 uniform_bones[128];" << std::endl; } if(instanced) { vertexSource << "uniform mat4 uniform_instanceTransform[128];" << std::endl; } vertexSource << "void main()" << std::endl; vertexSource << "{" << std::endl; if(skinned) { vertexSource << " mat4 boneTransform = uniform_bones[in_boneids[0]] * in_boneweights[0];" << std::endl; vertexSource << " boneTransform += uniform_bones[in_boneids[1]] * in_boneweights[1];" << std::endl; vertexSource << " boneTransform += uniform_bones[in_boneids[2]] * in_boneweights[2];" << std::endl; vertexSource << " boneTransform += uniform_bones[in_boneids[3]] * in_boneweights[3];" << std::endl; vertexSource << " vec4 position = boneTransform * vec4(in_vertexPos, 1.0);" << std::endl; } else { vertexSource << " vec4 position = vec4(in_vertexPos, 1.0);" << std::endl; } if(instanced) { vertexSource << " gl_Position = uniform_mvpMatrix * uniform_instanceTransform[gl_InstanceID] * position;" << std::endl; } else { vertexSource << " gl_Position = uniform_mvpMatrix * position;" << std::endl; } vertexSource << " out_uv = in_uv;" << std::endl; vertexSource << "}" << std::endl; } // Pixel shader std::stringstream pixelSource; auto pixelShader = new kit::Shader(Shader::Type::Fragment); { pixelSource << "#version 430 core" << std::endl; pixelSource << "layout(location = 0) in vec2 in_uv;" << std::endl; if(opacityMapped) { pixelSource << "uniform sampler2D uniform_opacityMask;" << std::endl; } pixelSource << "void main()" << std::endl; pixelSource << "{" << std::endl; if(opacityMapped) { pixelSource << " if(texture(uniform_opacityMask, in_uv).r < 0.5)" << std::endl; pixelSource << " {" << std::endl; pixelSource << " discard;" << std::endl; pixelSource << " }" << std::endl; } pixelSource << " gl_FragDepth = gl_FragCoord.z;" << std::endl; pixelSource << "}" << std::endl; } // Compile and link vertexShader->sourceFromString(vertexSource.str()); vertexShader->compile(); pixelShader->sourceFromString(pixelSource.str()); pixelShader->compile(); newProgram->attachShader(vertexShader); newProgram->attachShader(pixelShader); newProgram->link(); newProgram->detachShader(pixelShader); newProgram->detachShader(vertexShader); delete vertexShader; delete pixelShader; kit::Model::m_shadowPrograms[flags] = newProgram; return kit::Model::m_shadowPrograms.at(flags); }
bool ShaderProgram::loadShader(const std::string &vert_filename, const std::string &frag_filename, const std::string &geom_filename) { Shader* frag = 0; Shader* vert = 0; Shader* geom = 0; if (!vert_filename.empty()) { vert = new Shader(vert_filename, Shader::VERTEX_SHADER); if (!vert->loadSourceFromFile(vert_filename)) { printf("Failed to load vertex shader %s\n", vert_filename.c_str()); delete vert; return false; } else { vert->uploadSource(); if (!vert->compileShader()) { printf("Failed to compile vertex shader %s", vert_filename.c_str()); printf("Compiler Log: \n%s\n", vert->getCompilerLog().c_str()); delete vert; return false; } } } if (!geom_filename.empty()) { geom = new Shader(geom_filename, Shader::GEOMETRY_SHADER); if (!geom->loadSourceFromFile(geom_filename)) { printf("Failed to load geometry shader %s\n", geom_filename.c_str()); delete vert; delete geom; return false; } else { geom->uploadSource(); if (!geom->compileShader()) { printf("Failed to compile geometry shader %s\n", geom_filename.c_str()); printf("Compiler Log: \n%s\n", geom->getCompilerLog().c_str()); delete vert; delete geom; return false; } } } if (!frag_filename.empty()) { frag = new Shader(frag_filename, Shader::FRAGMENT_SHADER); if (!frag->loadSourceFromFile(frag_filename)) { printf("Failed to load fragment shader %s\n", frag_filename.c_str()); delete frag; delete geom; delete vert; return false; } else { frag->uploadSource(); if (!frag->compileShader()) { printf("Failed to compile fragment shader %s\n", frag_filename.c_str()); printf("Compiler Log: \n%s\n", frag->getCompilerLog().c_str()); delete vert; delete geom; delete frag; return false; } } } // Attach Shader, dtor will take care of freeing them if (frag) attachShader(frag); if (vert) attachShader(vert); if (geom) attachShader(geom); if (!linkProgram()) { printf("Failed to link shader (%s,%s,%s)\n", vert_filename.c_str(), frag_filename.c_str(), geom_filename.c_str()); if (vert) { printf("[%s] Vertex shader compiler log: \n%s\n",vert->filename.c_str(), vert->getCompilerLog().c_str()); detachShader(vert); delete vert; } if (geom) { printf("[%s] Geometry shader compiler log: \n%s\n",geom->filename.c_str(), geom->getCompilerLog().c_str()); detachShader(geom); delete geom; } if (frag) { printf("[%s] Fragment shader compiler log: \n%s\n",frag->filename.c_str(), frag->getCompilerLog().c_str()); detachShader(frag); delete frag; } printf("Linker Log: \n%s\n", getLinkerLog().c_str()); return false; } if (vert && vert->getCompilerLog().size() > 1) { printf("Vertex shader compiler log for file '%s': \n%s\n", vert_filename.c_str(), vert->getCompilerLog().c_str()); } if (geom && geom->getCompilerLog().size() > 1) { printf("Geometry shader compiler log for file '%s': \n%s\n", geom_filename.c_str(), geom->getCompilerLog().c_str()); } if (frag && frag->getCompilerLog().size() > 1) { printf("Fragment shader compiler log for file '%s': \n%s\n", frag_filename.c_str(), frag->getCompilerLog().c_str()); } if (getLinkerLog().size() > 1) { printf("Linker log for '%s' and '%s' and '%s': \n%s\n", vert_filename.c_str(), frag_filename.c_str(), geom_filename.c_str(), getLinkerLog().c_str()); } return true; }