From Brede Johansen,

"Geometry.cpp
Make sure number of normals match number of vertices when lit or
vertex-normal pairs are separated when geometries are merged by the
optimizer.

Ancillary.cpp
Improved support for multitexture effect field and use texture
environment from .attr file.

PaletteRecords.cpp
Use search path when looking for shader files.

PrimaryRecords.cpp
Added preset uniforms "TextureUnit0", "TextureUnit1", "TextureUnit2"
and "TextureUnit3" for GLSL shaders."
This commit is contained in:
Robert Osfield 2007-02-13 14:19:39 +00:00
parent cd07fb61eb
commit 927dfc0a52
4 changed files with 85 additions and 11 deletions

View File

@ -6,6 +6,7 @@
#include <osg/MatrixTransform> #include <osg/MatrixTransform>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/TexEnv>
#include "Registry.h" #include "Registry.h"
#include "Document.h" #include "Document.h"
@ -116,6 +117,13 @@ class Multitexture : public Record
META_Record(Multitexture) META_Record(Multitexture)
// Effect
enum EffectMode
{
TEXTURE_ENVIRONMENT = 0,
BUMP_MAP = 1
};
protected: protected:
virtual ~Multitexture() {} virtual ~Multitexture() {}
@ -131,16 +139,40 @@ class Multitexture : public Record
if (mask & layerBit) if (mask & layerBit)
{ {
int16 textureIndex = in.readInt16(); int16 textureIndex = in.readInt16();
/* int16 effectIndex =*/ in.readInt16(); int16 effect = in.readInt16();
/*int16 mappingIndex =*/ in.readInt16(); /*int16 mappingIndex =*/ in.readInt16();
/*uint16 data =*/ in.readUInt16(); /*uint16 data =*/ in.readUInt16();
osg::ref_ptr<osg::StateSet> texturePoolStateset = document.getOrCreateTexturePool()->get(textureIndex); osg::ref_ptr<osg::StateSet> texturePoolStateset = document.getOrCreateTexturePool()->get(textureIndex);
if (stateset.valid() && texturePoolStateset.valid()) if (stateset.valid() && texturePoolStateset.valid())
{ {
osg::Texture2D* texture = dynamic_cast<osg::Texture2D*>(texturePoolStateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE)); // Apply texture from texture pool.
osg::Texture* texture = dynamic_cast<osg::Texture*>(texturePoolStateset->getTextureAttribute(0,osg::StateAttribute::TEXTURE));
if (texture) if (texture)
stateset->setTextureAttributeAndModes(layer,texture,osg::StateAttribute::ON); stateset->setTextureAttributeAndModes(layer,texture,osg::StateAttribute::ON);
// Apply texture environment
switch (effect)
{
case TEXTURE_ENVIRONMENT:
{
// Use texture environment setting from .attr file.
osg::TexEnv* texenv = dynamic_cast<osg::TexEnv*>(texturePoolStateset->getTextureAttribute(0,osg::StateAttribute::TEXENV));
if (texenv)
stateset->setTextureAttribute(layer,texenv);
}
break;
case BUMP_MAP:
{
// Dot3 bumpmap
//osg::TexEnvCombine* texEnvCombine = new osg::TexEnvCombine;
//texEnvCombine->setCombine_RGB(osg::TexEnvCombine::DOT3_RGB);
//texEnvCombine->setSource0_RGB(osg::TexEnvCombine::PRIMARY_COLOR);
//texEnvCombine->setSource1_RGB(osg::TexEnvCombine::TEXTURE);
//stateset->setTextureAttribute(layer,texEnvCombine);
}
break;
}
} }
} }
} }

View File

@ -148,11 +148,34 @@ public:
} }
} }
bool strict = false; // prepare for "strict" reader option.
if (strict)
{
if (vertex.validNormal()) if (vertex.validNormal())
{ {
osg::Vec3Array* normals = getOrCreateNormalArray(*_geometry); osg::Vec3Array* normals = getOrCreateNormalArray(*_geometry);
normals->push_back(vertex._normal); normals->push_back(vertex._normal);
} }
}
else
{
// Add normal only if lit.
if (isLit())
{
osg::Vec3Array* normals = getOrCreateNormalArray(*_geometry);
if (vertex.validNormal())
normals->push_back(vertex._normal);
else // if lit and no normal in Vertex
{
// Use previous normal if available.
if (normals->empty())
normals->push_back(osg::Vec3(0,0,1));
else
normals->push_back(normals->back());
}
}
}
for (int layer=0; layer<Vertex::MAX_LAYERS; layer++) for (int layer=0; layer<Vertex::MAX_LAYERS; layer++)
{ {

View File

@ -762,12 +762,13 @@ protected:
osg::Program* program = new osg::Program; osg::Program* program = new osg::Program;
program->setName(name); program->setName(name);
// Read vertex programs
int idx; int idx;
for( idx=0; idx<vertexProgramFileCount; idx++) for( idx=0; idx<vertexProgramFileCount; idx++)
{ {
std::string vertexProgramFilename = in.readString(1024); std::string vertexProgramFilename = in.readString(1024);
std::string vertexProgramFilePath = osgDB::findDataFile(vertexProgramFilename); std::string vertexProgramFilePath = osgDB::findDataFile(vertexProgramFilename,document.getOptions());
if (!vertexProgramFilePath.empty()) if (!vertexProgramFilePath.empty())
{ {
osg::Shader* vertexShader = osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexProgramFilePath); osg::Shader* vertexShader = osg::Shader::readShaderFile(osg::Shader::VERTEX, vertexProgramFilePath);
@ -775,11 +776,13 @@ protected:
program->addShader( vertexShader ); program->addShader( vertexShader );
} }
} }
// Read fragment programs
for( idx=0; idx<fragmentProgramFileCount; idx++) for( idx=0; idx<fragmentProgramFileCount; idx++)
{ {
std::string fragmentProgramFilename = in.readString(1024); std::string fragmentProgramFilename = in.readString(1024);
std::string fragmentProgramFilePath = osgDB::findDataFile(fragmentProgramFilename); std::string fragmentProgramFilePath = osgDB::findDataFile(fragmentProgramFilename,document.getOptions());
if (!fragmentProgramFilePath.empty()) if (!fragmentProgramFilePath.empty())
{ {
osg::Shader* fragmentShader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentProgramFilePath); osg::Shader* fragmentShader = osg::Shader::readShaderFile(osg::Shader::FRAGMENT, fragmentProgramFilePath);
@ -788,6 +791,7 @@ protected:
} }
} }
// Add to shader pool
ShaderPool* shaderPool = document.getOrCreateShaderPool(); ShaderPool* shaderPool = document.getOrCreateShaderPool();
(*shaderPool)[index] = program; (*shaderPool)[index] = program;
} }

View File

@ -119,6 +119,21 @@ protected:
document.setHeaderNode(_header.get()); document.setHeaderNode(_header.get());
} }
virtual void popLevel(Document& document)
{
if (_header.valid())
{
// Preset sampler uniforms.
ShaderPool* sp = document.getShaderPool();
if (sp && !sp->empty())
{
_header->getOrCreateStateSet()->addUniform( new osg::Uniform("TextureUnit0", 0) );
_header->getOrCreateStateSet()->addUniform( new osg::Uniform("TextureUnit1", 1) );
_header->getOrCreateStateSet()->addUniform( new osg::Uniform("TextureUnit2", 2) );
_header->getOrCreateStateSet()->addUniform( new osg::Uniform("TextureUnit3", 3) );
}
}
}
}; };
RegisterRecordProxy<Header> g_Header(HEADER_OP); RegisterRecordProxy<Header> g_Header(HEADER_OP);