void ShaderGenVisitor::update(osg::Drawable *drawable) { // update only geometry due to compatibility issues with user defined drawables osg::Geometry *geometry = drawable->asGeometry(); #if 0 if (!geometry) return; #endif StateEx *state = static_cast<StateEx *>(_state.get()); // skip nodes without state sets if (state->getStateSetStackSize() == (_rootStateSet.valid() ? 1u : 0u)) return; // skip state sets with already attached programs if (state->getAttribute(osg::StateAttribute::PROGRAM)) return; int stateMask = 0; //if (state->getMode(GL_BLEND) & osg::StateAttribute::ON) // stateMask |= ShaderGen::BLEND; if (state->getMode(GL_LIGHTING) & osg::StateAttribute::ON) stateMask |= ShaderGenCache::LIGHTING; if (state->getMode(GL_FOG) & osg::StateAttribute::ON) stateMask |= ShaderGenCache::FOG; if (state->getTextureAttribute(0, osg::StateAttribute::TEXTURE)) stateMask |= ShaderGenCache::DIFFUSE_MAP; if (state->getTextureAttribute(1, osg::StateAttribute::TEXTURE) && geometry!=0 && geometry->getVertexAttribArray(6)) //tangent stateMask |= ShaderGenCache::NORMAL_MAP; // Get program and uniforms for accumulated state. osg::StateSet *progss = _stateCache->getOrCreateStateSet(stateMask); // Set program and uniforms to the last state set. osg::StateSet *ss = const_cast<osg::StateSet *>(state->getStateSetStack().back()); ss->setAttribute(progss->getAttribute(osg::StateAttribute::PROGRAM)); ss->setUniformList(progss->getUniformList()); // remove any modes that won't be appropriate when using shaders if ((stateMask&ShaderGenCache::LIGHTING)!=0) { ss->removeMode(GL_LIGHTING); ss->removeMode(GL_LIGHT0); } if ((stateMask&ShaderGenCache::FOG)!=0) { ss->removeMode(GL_FOG); } if ((stateMask&ShaderGenCache::DIFFUSE_MAP)!=0) ss->removeTextureMode(0, GL_TEXTURE_2D); if ((stateMask&ShaderGenCache::NORMAL_MAP)!=0) ss->removeTextureMode(1, GL_TEXTURE_2D); }
void GLES2ShaderGenVisitor::update(osg::Drawable *drawable) { // update only geometry due to compatibility issues with user defined drawables osg::Geometry *geometry = drawable->asGeometry(); #if 1 if (!geometry) return; #endif OSG_INFO << "Updating GEOMETRY 1" <<std::endl; StateEx *state = static_cast<StateEx *>(_state.get()); // skip nodes without state sets if (state->getStateSetStackSize() == (_rootStateSet.valid() ? 1u : 0u)) return; OSG_INFO << "Updating GEOMETRY 2" <<std::endl; // skip state sets with already attached programs if (state->getAttribute(osg::StateAttribute::PROGRAM)) return; OSG_INFO << "Updating GEOMETRY 3" <<std::endl; int stateMask = 0; //if (state->getMode(GL_BLEND) & osg::StateAttribute::ON) // stateMask |= ShaderGen::BLEND; if (state->getMode(GL_LIGHTING) & osg::StateAttribute::ON) stateMask |= GLES2ShaderGenCache::LIGHTING; if (state->getMode(GL_FOG) & osg::StateAttribute::ON) stateMask |= GLES2ShaderGenCache::FOG; if (state->getTextureAttribute(0, osg::StateAttribute::TEXTURE)) stateMask |= GLES2ShaderGenCache::DIFFUSE_MAP; if (state->getTextureAttribute(1, osg::StateAttribute::TEXTURE) && geometry!=0 && geometry->getVertexAttribArray(6)) //tangent stateMask |= GLES2ShaderGenCache::NORMAL_MAP; // Get program and uniforms for accumulated state. osg::StateSet *progss = _stateCache->getOrCreateStateSet(stateMask); // Set program and uniforms to the last state set. osg::StateSet *ss = const_cast<osg::StateSet *>(state->getStateSetStack().back()); ss->setAttribute(progss->getAttribute(osg::StateAttribute::PROGRAM)); ss->setUniformList(progss->getUniformList()); //Edit, for now we will pinch the Material colors and bind as uniforms for non fixed function to replace gl_Front Material #ifndef OSG_GL_FIXED_FUNCTION_AVAILABLE OSG_INFO << "Updating GEOMETRY material" <<std::endl; osg::Material* mat = dynamic_cast<osg::Material*>(ss->getAttribute(osg::StateAttribute::MATERIAL)); if(mat){ ss->addUniform(new osg::Uniform("osg_Material.ambient", mat->getAmbient(osg::Material::FRONT_AND_BACK))); ss->addUniform(new osg::Uniform("osg_Material.diffuse", mat->getDiffuse(osg::Material::FRONT_AND_BACK))); ss->addUniform(new osg::Uniform("osg_Material.specular", mat->getSpecular(osg::Material::FRONT_AND_BACK))); ss->addUniform(new osg::Uniform("osg_Material.shine", mat->getShininess(osg::Material::FRONT_AND_BACK))); ss->removeAttribute(osg::StateAttribute::MATERIAL); osg::notify(osg::NOTICE) << "----------- Generated material" << std::endl; }else{ //if no material then setup some reasonable defaults ss->addUniform(new osg::Uniform("osg_Material.ambient", osg::Vec4(0.2f,0.2f,0.2f,1.0f))); ss->addUniform(new osg::Uniform("osg_Material.diffuse", osg::Vec4(0.8f,0.8f,0.8f,1.0f))); ss->addUniform(new osg::Uniform("osg_Material.specular", osg::Vec4(1.0f,1.0f,1.0f,1.0f))); ss->addUniform(new osg::Uniform("osg_Material.shine", 16.0f)); } #endif // remove any modes that won't be appropriate when using shaders if ((stateMask & GLES2ShaderGenCache::LIGHTING)!=0) { ss->removeMode(GL_LIGHTING); ss->removeMode(GL_LIGHT0); } if ((stateMask & GLES2ShaderGenCache::FOG)!=0) { ss->removeMode(GL_FOG); } if ((stateMask & GLES2ShaderGenCache::DIFFUSE_MAP)!=0) ss->removeTextureMode(0, GL_TEXTURE_2D); if ((stateMask & GLES2ShaderGenCache::NORMAL_MAP)!=0) ss->removeTextureMode(1, GL_TEXTURE_2D); }