more effects features
Materials can specify an effect. Add support for PolygonMode and initial support for Uniform.
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user