#include "material.hpp" #include #include #include namespace SceneUtil { Material::Material(const MaterialConfig& config) : osg::StateAttribute() , mConfig(config) { } Material::Material(const Material& other, const osg::CopyOp& copyop) : osg::StateAttribute(other, copyop) , mConfig(other.mConfig) { } void Material::apply(osg::State& state) const {} void Material::ensureUniforms() const { std::lock_guard lock(mUniformMutex); if (mUniformDiffuse) return; mUniformDiffuse = new osg::Uniform("material.diffuse", mConfig.mDiffuse); mUniformAmbient = new osg::Uniform("material.ambient", mConfig.mAmbient); mUniformSpecular = new osg::Uniform("material.specular", mConfig.mSpecular); mUniformEmission = new osg::Uniform("material.emission", mConfig.mEmission); mUniformShininess = new osg::Uniform("material.shininess", mConfig.mShininess); mUniformEmissiveMult = new osg::Uniform("material.emissiveMult", mConfig.mEmissiveMult); mUniformSpecStrength = new osg::Uniform("material.specStrength", mConfig.mSpecularStrength); mUniformVertexColorMode = new osg::Uniform("material.vertexColorMode", static_cast(mConfig.mVertexColorMode)); } void Material::setStateSet(osg::StateSet* stateset, osg::StateAttribute::OverrideValue overrideValue) const { ensureUniforms(); stateset->addUniform(mUniformDiffuse, overrideValue); stateset->addUniform(mUniformAmbient, overrideValue); stateset->addUniform(mUniformSpecular, overrideValue); stateset->addUniform(mUniformEmission, overrideValue); stateset->addUniform(mUniformShininess, overrideValue); stateset->addUniform(mUniformEmissiveMult, overrideValue); stateset->addUniform(mUniformSpecStrength, overrideValue); stateset->addUniform(mUniformVertexColorMode, overrideValue); } void Material::updateStateSet(osg::StateSet* stateset) const { ensureUniforms(); stateset->addUniform(mUniformDiffuse); stateset->addUniform(mUniformAmbient); stateset->addUniform(mUniformSpecular); stateset->addUniform(mUniformEmission); stateset->addUniform(mUniformShininess); stateset->addUniform(mUniformEmissiveMult); stateset->addUniform(mUniformSpecStrength); stateset->addUniform(mUniformVertexColorMode); } void Material::setDiffuse(const osg::Vec4f& diffuse) { mConfig.mDiffuse = diffuse; std::lock_guard lock(mUniformMutex); if (mUniformDiffuse) mUniformDiffuse->set(diffuse); } void Material::setAmbient(const osg::Vec4f& ambient) { mConfig.mAmbient = ambient; std::lock_guard lock(mUniformMutex); if (mUniformAmbient) mUniformAmbient->set(ambient); } void Material::setSpecular(const osg::Vec4f& specular) { mConfig.mSpecular = specular; std::lock_guard lock(mUniformMutex); if (mUniformSpecular) mUniformSpecular->set(specular); } void Material::setEmission(const osg::Vec4f& emission) { mConfig.mEmission = emission; std::lock_guard lock(mUniformMutex); if (mUniformEmission) mUniformEmission->set(emission); } void Material::setShininess(float shininess) { mConfig.mShininess = shininess; std::lock_guard lock(mUniformMutex); if (mUniformShininess) mUniformShininess->set(shininess); } void Material::setEmissiveMultiplier(float mult) { mConfig.mEmissiveMult = mult; std::lock_guard lock(mUniformMutex); if (mUniformEmissiveMult) mUniformEmissiveMult->set(mult); } void Material::setSpecularStrength(float strength) { mConfig.mSpecularStrength = strength; std::lock_guard lock(mUniformMutex); if (mUniformSpecStrength) mUniformSpecStrength->set(strength); } void Material::setAlpha(float alpha) { float clamped = std::clamp(alpha, 0.f, 1.f); mConfig.mDiffuse[3] = clamped; mConfig.mAmbient[3] = clamped; mConfig.mSpecular[3] = clamped; mConfig.mEmission[3] = clamped; std::lock_guard lock(mUniformMutex); if (mUniformDiffuse) mUniformDiffuse->set(mConfig.mDiffuse); if (mUniformAmbient) mUniformAmbient->set(mConfig.mAmbient); if (mUniformSpecular) mUniformSpecular->set(mConfig.mSpecular); if (mUniformEmission) mUniformEmission->set(mConfig.mEmission); } void Material::setVertexColorMode(VertexColorModes mode) { mConfig.mVertexColorMode = mode; std::lock_guard lock(mUniformMutex); if (mUniformVertexColorMode) mUniformVertexColorMode->set(static_cast(mode)); } int Material::compare(const StateAttribute& sa) const { COMPARE_StateAttribute_Types(Material, sa); COMPARE_StateAttribute_Parameter(mConfig.mDiffuse); COMPARE_StateAttribute_Parameter(mConfig.mAmbient); COMPARE_StateAttribute_Parameter(mConfig.mSpecular); COMPARE_StateAttribute_Parameter(mConfig.mEmission); COMPARE_StateAttribute_Parameter(mConfig.mShininess); COMPARE_StateAttribute_Parameter(mConfig.mEmissiveMult); COMPARE_StateAttribute_Parameter(mConfig.mSpecularStrength); COMPARE_StateAttribute_Parameter(mConfig.mVertexColorMode); return 0; } bool Material::operator==(const Material& other) const { return (mConfig.mDiffuse == other.mConfig.mDiffuse && mConfig.mAmbient == other.mConfig.mAmbient && mConfig.mSpecular == other.mConfig.mSpecular && mConfig.mEmission == other.mConfig.mEmission && mConfig.mShininess == other.mConfig.mShininess && mConfig.mEmissiveMult == other.mConfig.mEmissiveMult && mConfig.mSpecularStrength == other.mConfig.mSpecularStrength && mConfig.mVertexColorMode == other.mConfig.mVertexColorMode); } }