From: Marcus G. <mgo...@go...> - 2009-06-27 14:41:00
|
Hi all, I'm trying to implement a GLSL shader for bumpmapping. The geometry is loaded from a VRML-file, which is loaded by the osg::SceneFileHandler. This works just fine and the object is rendered correctly. To compute the tangentspace I'm using calcVertexTangents, but this call crashes on some VRML-files and I'd like to understand why. I'm getting a "index out of range" exception in calcVertexTangents() on line 780 in OSGGeoFunctions.cpp. [.] // set value for every vertex int tanOffset = (imsize == 0) ? 0 : imsize-1; for (k=0; k<3; ++k) { tangent[v[k]] += sdir; //<-- here binormal[v[k]] += tdir; normal[v[k]] = tI.getNormal(k); ip->setValue(v[k], tI.getIndexIndex(k) + tanOffset); } [.] Maybe someone knows how to solve this. Code and shader is attached. Thanks in advance. Marcus -------------------------------------------------------------------- ------------------------------- CODE ------------------------------- -------------------------------------------------------------------- ShaderManager::ShaderManager(std::string _rootPath){ m_shaderMaterial = NullFC; m_simpleMaterial = NullFC; m_rootPath = _rootPath; // init material m_shaderMaterial = createShaderMaterial(); } //-------------------------------------------------------------------------- ------- ShaderManager::~ShaderManager(){ } //-------------------------------------------------------------------------- ------- void ShaderManager::assignShader( osg::NodePtr _parentNode ) { std::vector<osg::ChunkMaterialPtr> materials; std::vector<osg::GeometryPtr> geos; // get all the Materials of the current scene getAllMaterials( _parentNode, materials ); getGeometries( _parentNode, geos ); // add the material chunk to each found material for ( std::vector<osg::GeometryPtr>::iterator geoIter = geos.begin(); geoIter != geos.end(); geoIter++) { try { // compute tangentspace - crashes sometimes calcVertexTangents(*geoIter, 0, Geometry::TexCoords1FieldId, Geometry::TexCoords2FieldId); for (int i=0; i<materials.size(); i++) { beginEditCP(materials[i]); (materials[i])->addChunk(m_shaderMaterial); endEditCP(materials[i]); } } catch(...) { Tracer::warning("Shadermanager","assignShader", "Could not calculate tangentspace."); } } } //-------------------------------------------------------------------------- ------- SHLChunkPtr ShaderManager::createShaderMaterial(){ Tracer::info ("ShaderManager", "createShaderMaterial", "Creating shader..."); std::string _vp_program = Toolbox::readTextFile((m_rootPath + "\\normalmap.vert").c_str()); std::string _fp_program = Toolbox::readTextFile((m_rootPath + "\\normalmap.frag").c_str()); SHLChunkPtr _shl = SHLChunk::create(); beginEditCP(_shl); _shl->setVertexProgram(_vp_program); _shl->setFragmentProgram(_fp_program); _shl->setUniformParameter("colorMap", 0); _shl->setUniformParameter("normalMap", 1); endEditCP(_shl); Tracer::info ("ShaderManager", "createShaderMaterial", "Shader loaded."); return _shl; } //-------------------------------------------------------------------------- ------- ChunkMaterialPtr ShaderManager::getChunkMaterial(OSG::NodePtr node){ NodeCorePtr pCore = node->getCore(); ChunkMaterialPtr cm = NullFC; if ( pCore != NullFC && pCore->getType().isDerivedFrom(MaterialGroup::getClassType()) ) { MaterialGroupPtr g = MaterialGroupPtr::dcast(pCore); cm = ChunkMaterialPtr::dcast(g->getMaterial()); } else if ( pCore != NullFC && pCore->getType().isDerivedFrom(Geometry::getClassType()) ) { GeometryPtr g = GeometryPtr::dcast(pCore); cm = ChunkMaterialPtr::dcast(g->getMaterial()); } return cm; } //-------------------------------------------------------------------------- ------- void ShaderManager::getAllMaterials( NodePtr node,std::vector<ChunkMaterialPtr> &mats){ ChunkMaterialPtr cm = getChunkMaterial(node); if(cm != NullFC){ mats.push_back(cm); } for (int i=0; i<node->getNChildren(); i++) getAllMaterials(node->getChild(i),mats); } //-------------------------------------------------------------------------- ------- void ShaderManager::getGeometries( osg::NodePtr node,std::vector<osg::GeometryPtr> &geos) { if(node->getCore()->getType().isDerivedFrom( Geometry::getClassType())) geos.push_back(GeometryPtr::dcast(node->getCore())); for (int i=0; i<node->getNChildren(); i++) getGeometries(node->getChild(i),geos); } //-------------------------------------------------------------------------- ------- -------------------------------------------------------------------- ------------------------------ SHADER ------------------------------ -------------------------------------------------------------------- varying vec3 lightVec; varying vec3 eyeVec; varying vec2 texCoord; void main(void) { gl_Position = ftransform(); texCoord = gl_MultiTexCoord0.xy; vec3 t = normalize(gl_NormalMatrix * gl_MultiTexCoord1.xyz); vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); vec3 n = normalize(gl_NormalMatrix * gl_Normal); vec3 vVertex = vec3(gl_ModelViewMatrix * gl_Vertex); vec3 tmpVec = gl_LightSource[0].position.xyz - vVertex; lightVec.x = dot(tmpVec, t); lightVec.y = dot(tmpVec, b); lightVec.z = dot(tmpVec, n); tmpVec = -vVertex; eyeVec.x = dot(tmpVec, t); eyeVec.y = dot(tmpVec, b); eyeVec.z = dot(tmpVec, n); } -------------------------------------------------------------------- varying vec3 lightVec; varying vec3 eyeVec; varying vec2 texCoord; uniform sampler2D colorMap; uniform sampler2D normalMap; void main (void) { vec3 lVec = normalize(lightVec); vec3 vVec = normalize(eyeVec); vec4 base = texture2D(colorMap, texCoord); vec3 bump = normalize( texture2D(normalMap, texCoord).xyz * 2.0 - 1.0); vec4 vAmbient = gl_LightSource[0].ambient * gl_FrontMaterial.ambient; float diffuse = max( dot(lVec, bump), 0.0 ); vec4 vDiffuse = gl_LightSource[0].diffuse * gl_FrontMaterial.diffuse * diffuse; float specular = pow(clamp(dot(reflect(-lVec, bump), vVec), 0.0, 1.0), gl_FrontMaterial.shininess ); vec4 vSpecular = gl_LightSource[0].specular * gl_FrontMaterial.specular * specular; gl_FragColor = ( vAmbient*base + vDiffuse*base + vSpecular); } |