ShaderProgram& ShaderAssembler::getShader(const uint64 materialAttribs, const uint64 drawableAttribs) { JOP_ASSERT(m_instance != nullptr, "Couldn't load shader, no ShaderAssembler instance!"); auto& cont = m_instance->m_shaders; const std::size_t combinedAttribs = combinedHash(materialAttribs, drawableAttribs); { std::unique_lock<std::recursive_mutex> lock(m_instance->m_mutex); auto itr = cont.find(combinedAttribs); if (itr != cont.end() && !itr->second.expired()) return *itr->second; } const auto& uber = m_instance->m_uber; const std::string shaderName = "jop_shader_" + std::to_string(combinedAttribs); std::string pp = Material::getShaderPreprocessorDef(materialAttribs) + Drawable::getShaderPreprocessorDef(drawableAttribs); ShaderProgram* s = &ResourceManager::getNamed<ShaderProgram>(shaderName, pp, Shader::Type::Vertex, uber[0], Shader::Type::Geometry, uber[1], Shader::Type::Fragment, uber[2]); if (!ResourceManager::isError(*s)) { s->setShouldSerialize(false); s->setPersistence(5); { std::unique_lock<std::recursive_mutex> lock(m_instance->m_mutex); cont[combinedAttribs] = static_ref_cast<ShaderProgram>(s->getReference()); } // Needed so that different samplers don't all point to zero if ((materialAttribs & Material::FragLightingAttribs) != 0) { static const int maxUnits = Texture::getMaxTextureUnits(); for (std::size_t i = 0; i < LightSource::getMaximumLights(LightSource::Type::Point); ++i) s->setUniform("u_PointLightShadowMaps[" + std::to_string(i) + "]", maxUnits - 1); } } return *s; }
void Drawable::setOverrideShader(ShaderProgram& shader) { m_shader = static_ref_cast<ShaderProgram>(shader.getReference()); }