From e3646d4d4a22224946a3b929ec776b958b9dfc51 Mon Sep 17 00:00:00 2001 From: timoore Date: Wed, 15 Jul 2009 23:11:44 +0000 Subject: [PATCH] more effects features Materials can specify an effect. Add support for PolygonMode and initial support for Uniform. --- simgear/scene/material/Effect.cxx | 118 +++++++++++++++++++++++++++++- simgear/scene/material/mat.cxx | 7 +- simgear/scene/material/mat.hxx | 3 + 3 files changed, 125 insertions(+), 3 deletions(-) diff --git a/simgear/scene/material/Effect.cxx b/simgear/scene/material/Effect.cxx index c1db1d73..3969419d 100644 --- a/simgear/scene/material/Effect.cxx +++ b/simgear/scene/material/Effect.cxx @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -667,7 +669,9 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, if (sitr != shaderMap.end()) { program->addShader(sitr->second.get()); } else { - string fileName = osgDB::findDataFile(shaderName, options); + string fileName = osgDB::Registry::instance() + ->findDataFile(shaderName, options, + osgDB::CASE_SENSITIVE); if (!fileName.empty()) { ref_ptr shader = new Shader(stype); if (shader->loadShaderSourceFromFile(fileName)) { @@ -685,6 +689,86 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass, pass->setAttributeAndModes(program); } +InstallAttributeBuilder installShaderProgram("program"); + +EffectNameValue uniformTypes[] = +{ + {"float", Uniform::FLOAT}, + {"float-vec3", Uniform::FLOAT_VEC3}, + {"float-vec4", Uniform::FLOAT_VEC4}, + {"sampler-1d", Uniform::SAMPLER_1D}, + {"sampler-2d", Uniform::SAMPLER_2D}, + {"sampler-3d", Uniform::SAMPLER_3D} +}; + +struct UniformBuilder :public PassAttributeBuilder +{ + void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, + const osgDB::ReaderWriter::Options* options) + { + using namespace simgear::props; + const SGPropertyNode* nameProp = prop->getChild("name"); + const SGPropertyNode* typeProp = prop->getChild("type"); + const SGPropertyNode* valProp + = getEffectPropertyChild(effect, prop, "value"); + string name; + Uniform::Type uniformType = Uniform::FLOAT; + if (nameProp) { + name = nameProp->getStringValue(); + } else { + SG_LOG(SG_INPUT, SG_ALERT, "No name for uniform property "); + return; + } + if (!valProp) { + SG_LOG(SG_INPUT, SG_ALERT, "No value for uniform property " + << name); + return; + } + if (!typeProp) { + props::Type propType = valProp->getType(); + switch (propType) { + case FLOAT: + case DOUBLE: + break; // default float type; + case VEC3D: + uniformType = Uniform::FLOAT_VEC3; + break; + case VEC4D: + uniformType = Uniform::FLOAT_VEC4; + break; + default: + SG_LOG(SG_INPUT, SG_ALERT, "Can't deduce type of uniform " + << name); + return; + } + } else { + findAttr(uniformTypes, typeProp, uniformType); + } + ref_ptr uniform = new Uniform; + uniform->setName(name); + uniform->setType(uniformType); + switch (uniformType) { + case Uniform::FLOAT: + uniform->set(valProp->getValue()); + break; + case Uniform::FLOAT_VEC3: + uniform->set(Vec3f(valProp->getValue().osg())); + break; + case Uniform::FLOAT_VEC4: + uniform->set(Vec4f(valProp->getValue().osg())); + break; + case Uniform::SAMPLER_1D: + case Uniform::SAMPLER_2D: + case Uniform::SAMPLER_3D: + uniform->set(valProp->getValue()); + break; + } + pass->addUniform(uniform.get()); + } +}; + +InstallAttributeBuilder installUniform("uniform"); + // Not sure what to do with "name". At one point I wanted to use it to // order the passes, but I do support render bin and stuff too... @@ -702,6 +786,38 @@ struct NameBuilder : public PassAttributeBuilder InstallAttributeBuilder installName("name"); +EffectNameValue polygonModeModes[] = +{ + {"fill", PolygonMode::FILL}, + {"line", PolygonMode::LINE}, + {"point", PolygonMode::POINT} +}; + +struct PolygonModeBuilder : public PassAttributeBuilder +{ + void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, + const osgDB::ReaderWriter::Options* options) + { + const SGPropertyNode* frontProp + = getEffectPropertyChild(effect, prop, "front"); + const SGPropertyNode* backProp + = getEffectPropertyChild(effect, prop, "back"); + ref_ptr pmode = new PolygonMode; + PolygonMode::Mode frontMode = PolygonMode::FILL; + PolygonMode::Mode backMode = PolygonMode::FILL; + if (frontProp) { + findAttr(polygonModeModes, frontProp, frontMode); + pmode->setMode(PolygonMode::FRONT, frontMode); + } + if (backProp) { + findAttr(polygonModeModes, backProp, backMode); + pmode->setMode(PolygonMode::BACK, backMode); + } + pass->setAttribute(pmode.get()); + } +}; + +InstallAttributeBuilder installPolygonMode("polygon-mode"); void buildTechnique(Effect* effect, const SGPropertyNode* prop, const osgDB::ReaderWriter::Options* options) { diff --git a/simgear/scene/material/mat.cxx b/simgear/scene/material/mat.cxx index 1484c420..63b8aebd 100644 --- a/simgear/scene/material/mat.cxx +++ b/simgear/scene/material/mat.cxx @@ -176,6 +176,9 @@ SGMaterial::read_properties(const osgDB::Options* options, shininess = props->getDoubleValue("shininess", 1.0); + if (props->hasChild("effect")) + effect = props->getStringValue("effect"); + vector object_group_nodes = ((SGPropertyNode *)props)->getChildren("object-group"); for (unsigned int i = 0; i < object_group_nodes.size(); i++) @@ -222,6 +225,7 @@ SGMaterial::init () diffuse[i] = (i < 3) ? 0.8 : 1.0; emission[i] = (i < 3) ? 0.0 : 1.0; } + effect = "Effects/terrain-default"; } Effect* SGMaterial::get_effect(int n) @@ -246,8 +250,7 @@ void SGMaterial::buildEffectProperties(const osgDB::Options* options) { using namespace osg; SGPropertyNode_ptr propRoot = new SGPropertyNode(); - makeChild(propRoot, "inherits-from") - ->setStringValue("Effects/terrain-default"); + makeChild(propRoot, "inherits-from")->setStringValue(effect); SGPropertyNode* paramProp = makeChild(propRoot, "parameters"); SGPropertyNode* materialProp = makeChild(paramProp, "material"); makeChild(materialProp, "ambient")->setValue(SGVec4d(ambient)); diff --git a/simgear/scene/material/mat.hxx b/simgear/scene/material/mat.hxx index 1317072a..ae246ad5 100644 --- a/simgear/scene/material/mat.hxx +++ b/simgear/scene/material/mat.hxx @@ -326,6 +326,9 @@ private: SGVec4f ambient, diffuse, specular, emission; double shininess; + // effect for this material + std::string effect; + // the list of names for this material. May be empty. std::vector _names; -- 2.39.5