Added fallback textures to handle cases where no texture is provided
This commit is contained in:
parent
0bcfa8d980
commit
d1222fc2ef
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <osg/TexGen>
|
#include <osg/TexGen>
|
||||||
|
|
||||||
#include <osgDB/ReadFile>
|
#include <osgDB/ReadFile>
|
||||||
#include <osgDB/WriteFile>
|
#include <osgDB/WriteFile>
|
||||||
|
|
||||||
@ -55,6 +56,15 @@ bool readShaderArguments(osg::ArgumentParser& arguments, const std::string& opti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::Image* createFallbackImage()
|
||||||
|
{
|
||||||
|
osg::Image* image = new osg::Image;
|
||||||
|
image->allocateImage(1,1,1,GL_RGBA, GL_UNSIGNED_BYTE);
|
||||||
|
//image->setColor(osg::Vec4(1.0,1.0,0.0,1.0), 0, 0, 0);
|
||||||
|
*(reinterpret_cast<unsigned int*>(image->data())) = 0xffffffff;
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// use an ArgumentParser object to manage the program arguments.
|
// use an ArgumentParser object to manage the program arguments.
|
||||||
@ -82,6 +92,9 @@ int main(int argc, char** argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int maxTextureUnits = 1;
|
||||||
|
while(arguments.read("--units", maxTextureUnits)) {}
|
||||||
|
|
||||||
// assign program to topmost StateSet
|
// assign program to topmost StateSet
|
||||||
viewer.getCamera()->getOrCreateStateSet()->setAttribute(program);
|
viewer.getCamera()->getOrCreateStateSet()->setAttribute(program);
|
||||||
|
|
||||||
@ -97,7 +110,6 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
osg::ref_ptr<osg::StateSet> stateset = viewer.getCamera()->getOrCreateStateSet();
|
osg::ref_ptr<osg::StateSet> stateset = viewer.getCamera()->getOrCreateStateSet();
|
||||||
|
|
||||||
unsigned int maxTextureUnits = 1;
|
|
||||||
std::stringstream sstream;
|
std::stringstream sstream;
|
||||||
sstream<<maxTextureUnits;
|
sstream<<maxTextureUnits;
|
||||||
stateset->setDefine("GL_MAX_TEXTURE_UNITS", sstream.str());
|
stateset->setDefine("GL_MAX_TEXTURE_UNITS", sstream.str());
|
||||||
@ -109,6 +121,18 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (maxTextureUnits>0)
|
if (maxTextureUnits>0)
|
||||||
{
|
{
|
||||||
|
osg::ref_ptr<osg::Texture2D> fallbackTexture = new osg::Texture2D(createFallbackImage());
|
||||||
|
fallbackTexture->setWrap(osg::Texture2D::WRAP_S, osg::Texture2D::CLAMP_TO_EDGE);
|
||||||
|
fallbackTexture->setWrap(osg::Texture2D::WRAP_T, osg::Texture2D::CLAMP_TO_EDGE);
|
||||||
|
fallbackTexture->setWrap(osg::Texture2D::WRAP_R, osg::Texture2D::CLAMP_TO_EDGE);
|
||||||
|
fallbackTexture->setFilter(osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
fallbackTexture->setFilter(osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);
|
||||||
|
for(unsigned int i=0; i<maxTextureUnits;++i)
|
||||||
|
{
|
||||||
|
stateset->setTextureAttribute(i, fallbackTexture.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ADD_DEFINE(GL_EYE_LINEAR);
|
ADD_DEFINE(GL_EYE_LINEAR);
|
||||||
ADD_DEFINE(GL_OBJECT_LINEAR);
|
ADD_DEFINE(GL_OBJECT_LINEAR);
|
||||||
ADD_DEFINE(GL_SPHERE_MAP);
|
ADD_DEFINE(GL_SPHERE_MAP);
|
||||||
@ -155,7 +179,7 @@ int main(int argc, char** argv)
|
|||||||
sstream.str("");
|
sstream.str("");
|
||||||
sstream<<"sampler"<<i;
|
sstream<<"sampler"<<i;
|
||||||
OSG_NOTICE<<"****** texture unit : "<<sstream.str()<<std::endl;
|
OSG_NOTICE<<"****** texture unit : "<<sstream.str()<<std::endl;
|
||||||
stateset->addUniform(new osg::Uniform(sstream.str().c_str(), i));
|
stateset->addUniform(new osg::Uniform(sstream.str().c_str(), static_cast<int>(i)));
|
||||||
|
|
||||||
|
|
||||||
// fragment shader texture defines
|
// fragment shader texture defines
|
||||||
|
@ -882,6 +882,7 @@ class OSG_EXPORT State : public Referenced
|
|||||||
CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
|
CheckForGLErrors getCheckForGLErrors() const { return _checkGLErrors; }
|
||||||
|
|
||||||
bool checkGLErrors(const char* str1=0, const char* str2=0) const;
|
bool checkGLErrors(const char* str1=0, const char* str2=0) const;
|
||||||
|
bool checkGLErrors(const std::string& str) const;
|
||||||
bool checkGLErrors(StateAttribute::GLMode mode) const;
|
bool checkGLErrors(StateAttribute::GLMode mode) const;
|
||||||
bool checkGLErrors(const StateAttribute* attribute) const;
|
bool checkGLErrors(const StateAttribute* attribute) const;
|
||||||
|
|
||||||
@ -2043,6 +2044,7 @@ inline void State::applyAttributeListOnTexUnit(unsigned int unit,AttributeMap& a
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
inline void State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
|
inline void State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
|
||||||
{
|
{
|
||||||
if (!_lastAppliedProgramObject) return;
|
if (!_lastAppliedProgramObject) return;
|
||||||
@ -2116,6 +2118,7 @@ inline void State::applyUniformList(UniformMap& uniformMap,const StateSet::Unifo
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
inline void State::applyDefineList(DefineMap& defineMap, const StateSet::DefineList& defineList)
|
inline void State::applyDefineList(DefineMap& defineMap, const StateSet::DefineList& defineList)
|
||||||
{
|
{
|
||||||
|
@ -738,6 +738,8 @@ void State::apply(const StateSet* dstate)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("after attributes State::apply()");
|
||||||
|
|
||||||
if (dstate->getUniformList().empty())
|
if (dstate->getUniformList().empty())
|
||||||
{
|
{
|
||||||
if (_currentShaderCompositionUniformList.empty()) applyUniformMap(_uniformMap);
|
if (_currentShaderCompositionUniformList.empty()) applyUniformMap(_uniformMap);
|
||||||
@ -810,12 +812,95 @@ void State::apply()
|
|||||||
applyShaderComposition();
|
applyShaderComposition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("after attributes State::apply()");
|
||||||
|
|
||||||
if (_currentShaderCompositionUniformList.empty()) applyUniformMap(_uniformMap);
|
if (_currentShaderCompositionUniformList.empty()) applyUniformMap(_uniformMap);
|
||||||
else applyUniformList(_uniformMap, _currentShaderCompositionUniformList);
|
else applyUniformList(_uniformMap, _currentShaderCompositionUniformList);
|
||||||
|
|
||||||
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("end of State::apply()");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
void State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)
|
||||||
|
{
|
||||||
|
if (!_lastAppliedProgramObject) return;
|
||||||
|
|
||||||
|
StateSet::UniformList::const_iterator ds_aitr=uniformList.begin();
|
||||||
|
|
||||||
|
UniformMap::iterator this_aitr=uniformMap.begin();
|
||||||
|
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("start of State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)");
|
||||||
|
|
||||||
|
while (this_aitr!=uniformMap.end() && ds_aitr!=uniformList.end())
|
||||||
|
{
|
||||||
|
if (this_aitr->first<ds_aitr->first)
|
||||||
|
{
|
||||||
|
// note attribute type = this_aitr->first
|
||||||
|
UniformStack& as = this_aitr->second;
|
||||||
|
if (!as.uniformVec.empty())
|
||||||
|
{
|
||||||
|
_lastAppliedProgramObject->apply(*as.uniformVec.back().first);
|
||||||
|
}
|
||||||
|
|
||||||
|
++this_aitr;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (ds_aitr->first<this_aitr->first)
|
||||||
|
{
|
||||||
|
_lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
|
||||||
|
|
||||||
|
++ds_aitr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// this_mitr & ds_mitr refer to the same attribute, check the override
|
||||||
|
// if any otherwise just apply the incoming attribute
|
||||||
|
|
||||||
|
UniformStack& as = this_aitr->second;
|
||||||
|
|
||||||
|
if (!as.uniformVec.empty() && (as.uniformVec.back().second & StateAttribute::OVERRIDE) && !(ds_aitr->second.second & StateAttribute::PROTECTED))
|
||||||
|
{
|
||||||
|
// override is on, just treat as a normal apply on uniform.
|
||||||
|
_lastAppliedProgramObject->apply(*as.uniformVec.back().first);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no override on or no previous entry, therefore consider incoming attribute.
|
||||||
|
_lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
|
||||||
|
}
|
||||||
|
|
||||||
|
++this_aitr;
|
||||||
|
++ds_aitr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterator over the remaining state attributes to apply any previous changes.
|
||||||
|
for(;
|
||||||
|
this_aitr!=uniformMap.end();
|
||||||
|
++this_aitr)
|
||||||
|
{
|
||||||
|
// note attribute type = this_aitr->first
|
||||||
|
UniformStack& as = this_aitr->second;
|
||||||
|
if (!as.uniformVec.empty())
|
||||||
|
{
|
||||||
|
_lastAppliedProgramObject->apply(*as.uniformVec.back().first);
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(as.uniformVec.back().first->getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// iterator over the remaining incoming attribute to apply any new attribute.
|
||||||
|
for(;
|
||||||
|
ds_aitr!=uniformList.end();
|
||||||
|
++ds_aitr)
|
||||||
|
{
|
||||||
|
_lastAppliedProgramObject->apply(*(ds_aitr->second.first.get()));
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors(ds_aitr->second.first->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_checkGLErrors==ONCE_PER_ATTRIBUTE) checkGLErrors("after of State::applyUniformList(UniformMap& uniformMap,const StateSet::UniformList& uniformList)");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void State::applyShaderComposition()
|
void State::applyShaderComposition()
|
||||||
{
|
{
|
||||||
if (_shaderCompositionEnabled)
|
if (_shaderCompositionEnabled)
|
||||||
@ -1154,6 +1239,10 @@ unsigned int State::getClientActiveTextureUnit() const
|
|||||||
return _currentClientActiveTextureUnit;
|
return _currentClientActiveTextureUnit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool State::checkGLErrors(const std::string& str) const
|
||||||
|
{
|
||||||
|
return checkGLErrors(str.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
bool State::checkGLErrors(const char* str1, const char* str2) const
|
bool State::checkGLErrors(const char* str1, const char* str2) const
|
||||||
{
|
{
|
||||||
@ -1739,12 +1828,12 @@ void State::getDefineString(std::string& shaderDefineStr, const osg::ShaderPragm
|
|||||||
StringModeMap::iterator m_itr = _stringModeMap.find(modeStr);
|
StringModeMap::iterator m_itr = _stringModeMap.find(modeStr);
|
||||||
if (m_itr!=_stringModeMap.end())
|
if (m_itr!=_stringModeMap.end())
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<"Look up mode ["<<modeStr<<"]"<<std::endl;
|
// OSG_NOTICE<<"Look up mode ["<<modeStr<<"]"<<std::endl;
|
||||||
StateAttribute::GLMode mode = m_itr->second;
|
StateAttribute::GLMode mode = m_itr->second;
|
||||||
|
|
||||||
if (mode>=GL_TEXTURE0 && mode<=(GL_TEXTURE0+15))
|
if (mode>=GL_TEXTURE0 && mode<=(GL_TEXTURE0+15))
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<" Need to map GL_TEXTUREi"<<std::endl;
|
// OSG_NOTICE<<" Need to map GL_TEXTUREi"<<std::endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1754,7 +1843,7 @@ void State::getDefineString(std::string& shaderDefineStr, const osg::ShaderPragm
|
|||||||
bool mode_enabled = mm_itr->second.last_applied_value;
|
bool mode_enabled = mm_itr->second.last_applied_value;
|
||||||
if (mode_enabled)
|
if (mode_enabled)
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<" mapping mode to #define "<<modeStr<<std::endl;
|
// OSG_NOTICE<<" mapping mode to #define "<<modeStr<<std::endl;
|
||||||
shaderDefineStr += "#define ";
|
shaderDefineStr += "#define ";
|
||||||
shaderDefineStr += modeStr;
|
shaderDefineStr += modeStr;
|
||||||
shaderDefineStr += s_LineEnding;
|
shaderDefineStr += s_LineEnding;
|
||||||
@ -1779,7 +1868,7 @@ void State::getDefineString(std::string& shaderDefineStr, const osg::ShaderPragm
|
|||||||
StringModeMap::iterator m_itr = _stringModeMap.find(modeStr);
|
StringModeMap::iterator m_itr = _stringModeMap.find(modeStr);
|
||||||
if (m_itr!=_stringModeMap.end())
|
if (m_itr!=_stringModeMap.end())
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<"Need to look up mode ["<<modeStr<<"]"<<std::endl;
|
// OSG_NOTICE<<"Need to look up mode ["<<modeStr<<"]"<<std::endl;
|
||||||
StateAttribute::GLMode mode = m_itr->second;
|
StateAttribute::GLMode mode = m_itr->second;
|
||||||
ModeMap::const_iterator mm_itr = modeMap.find(mode);
|
ModeMap::const_iterator mm_itr = modeMap.find(mode);
|
||||||
if (mm_itr!=modeMap.end())
|
if (mm_itr!=modeMap.end())
|
||||||
@ -1787,7 +1876,7 @@ void State::getDefineString(std::string& shaderDefineStr, const osg::ShaderPragm
|
|||||||
bool mode_enabled = mm_itr->second.last_applied_value;
|
bool mode_enabled = mm_itr->second.last_applied_value;
|
||||||
if (mode_enabled)
|
if (mode_enabled)
|
||||||
{
|
{
|
||||||
OSG_NOTICE<<" mapping mode to #define "<<modeStr<<std::endl;
|
// OSG_NOTICE<<" mapping mode to #define "<<modeStr<<std::endl;
|
||||||
shaderDefineStr += "#define ";
|
shaderDefineStr += "#define ";
|
||||||
shaderDefineStr += modeStr;
|
shaderDefineStr += modeStr;
|
||||||
shaderDefineStr += s_LineEnding;
|
shaderDefineStr += s_LineEnding;
|
||||||
@ -1802,7 +1891,7 @@ void State::getDefineString(std::string& shaderDefineStr, const osg::ShaderPragm
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
OSG_NOTICE<<"State::getDefineString(..) "<<shaderDefineStr<<std::endl;
|
// OSG_NOTICE<<"State::getDefineString(..) "<<shaderDefineStr<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool State::supportsShaderRequirements(const osg::ShaderPragmas& shaderPragmas)
|
bool State::supportsShaderRequirements(const osg::ShaderPragmas& shaderPragmas)
|
||||||
|
Loading…
Reference in New Issue
Block a user