Shader::Shader( const std::string& name, const std::vector<Attribute>& attributes, const std::vector<Uniform>& uniforms) : gl_shader_(GLShader::compileAndLinkShader(kShaderPath + name + ".vert", kShaderPath + name + ".frag")), program_name_(name) { #ifdef SHADER_WARN std::clog << "Successfully compiled/linked shader: " << name << " as program: " << gl_shader_.program() << std::endl; #endif for (const auto& attr : attributes) { attribute_locations_.insert(std::make_pair( attr, gl_shader_.getAttributeLocation(attribute_name(attr)))); } for (const auto& uniform : uniforms) { uniform_locations_.insert(std::make_pair( uniform, gl_shader_.getUniformLocation(uniform_name(uniform)))); } }
boost::optional<std::pair<GLShaderHandle, GLUniformLocation>> Shader::uniformLocation( const Uniform& uniform) { if (uniform_locations_.count(uniform) == 0) { #ifdef SHADER_WARN std::clog << "Could not find uniform: " << uniform_name(uniform) << " in shader program: " << program_name_ << std::endl; #endif return boost::none; } return std::make_pair( gl_shader_.program(), uniform_locations_.at(uniform)); }
void Shader::addAllUniforms() { /* Get all active uniforms except uniforms in blocks */ GLenum program_interface = GL_UNIFORM; GLint num_uniforms = 0; glGetProgramInterfaceiv(m_program_id, program_interface, GL_ACTIVE_RESOURCES, &num_uniforms); const GLenum properties[] = { GL_BLOCK_INDEX, GL_TYPE, GL_NAME_LENGTH, GL_LOCATION }; const GLint properties_size = sizeof(properties) / sizeof(properties[0]); for(GLint i = 0; i < num_uniforms; ++i) { GLint values[properties_size]; glGetProgramResourceiv(m_program_id, program_interface, i, properties_size, properties, properties_size, nullptr, values); /* Skip all uniforms in blocks */ if(values[0] != -1) { continue; } std::vector<char> name_data(values[2]); glGetProgramResourceName(m_program_id, program_interface, i, name_data.size(), nullptr, &name_data[0]); std::string uniform_name(name_data.begin(), name_data.end() - 1); std::string prefix = uniform_name.substr(0, 2); if(GLOBAL_UNIFORM_PREFIX == prefix) { m_global_uniforms_types.push_back(values[1]); m_global_uniforms_names.push_back(uniform_name); m_uniforms_locations[uniform_name] = values[3]; } else if(SKIP_UNIFORM_PREFIX == prefix) { m_uniforms_locations[uniform_name] = values[3]; } else { m_uniforms_types.push_back(values[1]); m_uniforms_names.push_back(uniform_name); m_uniforms_locations[uniform_name] = values[3]; } } }