more effects features

Materials can specify an effect.

Add support for PolygonMode and initial support for Uniform.
This commit is contained in:
timoore
2009-07-15 23:11:44 +00:00
committed by Tim Moore
parent 4219f16f61
commit e3646d4d4a
3 changed files with 125 additions and 3 deletions

View File

@@ -33,6 +33,7 @@
#include <osg/CullFace>
#include <osg/Drawable>
#include <osg/Material>
#include <osg/PolygonMode>
#include <osg/Program>
#include <osg/Referenced>
#include <osg/RenderInfo>
@@ -40,6 +41,7 @@
#include <osg/StateSet>
#include <osg/TexEnv>
#include <osg/Texture2D>
#include <osg/Uniform>
#include <osg/Vec4d>
#include <osgUtil/CullVisitor>
#include <osgDB/FileUtils>
@@ -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> shader = new Shader(stype);
if (shader->loadShaderSourceFromFile(fileName)) {
@@ -685,6 +689,86 @@ void ShaderProgramBuilder::buildAttribute(Effect* effect, Pass* pass,
pass->setAttributeAndModes(program);
}
InstallAttributeBuilder<ShaderProgramBuilder> installShaderProgram("program");
EffectNameValue<Uniform::Type> 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> uniform = new Uniform;
uniform->setName(name);
uniform->setType(uniformType);
switch (uniformType) {
case Uniform::FLOAT:
uniform->set(valProp->getValue<float>());
break;
case Uniform::FLOAT_VEC3:
uniform->set(Vec3f(valProp->getValue<SGVec3d>().osg()));
break;
case Uniform::FLOAT_VEC4:
uniform->set(Vec4f(valProp->getValue<SGVec4d>().osg()));
break;
case Uniform::SAMPLER_1D:
case Uniform::SAMPLER_2D:
case Uniform::SAMPLER_3D:
uniform->set(valProp->getValue<int>());
break;
}
pass->addUniform(uniform.get());
}
};
InstallAttributeBuilder<UniformBuilder> 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<NameBuilder> installName("name");
EffectNameValue<PolygonMode::Mode> 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<PolygonMode> 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<PolygonModeBuilder> installPolygonMode("polygon-mode");
void buildTechnique(Effect* effect, const SGPropertyNode* prop,
const osgDB::ReaderWriter::Options* options)
{

View File

@@ -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<SGPropertyNode_ptr> 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));

View File

@@ -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<std::string> _names;