I found a solution which involves computing the barycentric coordinates. However it seems that is not working properly.
To compute the barycentric coordinates I need to associate to the vertices of the triangles a coordinate among (1,0,0) (0,1,0) (0,0,1) for doing that I use the following function, which is based on the assumption I load the 3d model using the option noTriStripPolygons so that each polygon is a triangle (and not a strip of triangles). Code: void OSGGraphicsUtils::setBarycentricCoordinates(osg::Node * object, osg::Program *shaderProgram) { GeodeFinder myGeodeFinder; std::vector< osg::Geode *> listOfGeodes; object->accept(myGeodeFinder); listOfGeodes = myGeodeFinder.getNodeList(); std::cout << "there are " << listOfGeodes.size() << " geodes" << std::endl; for (int j = 0; j < listOfGeodes.size() ; j++) { //get the current geode osg::Geode* currentGeode = listOfGeodes.at(j); if (currentGeode != NULL) { for (int i = 0; i < currentGeode->getNumDrawables(); i++) { osg::Geometry *cubeGeometry = currentGeode->getDrawable(i)->asGeometry(); if (!cubeGeometry) continue; int numAttribs = cubeGeometry->getVertexArray()->getNumElements(); std::cout<< "number of vertices is "<<numAttribs<<std::endl; osg::ref_ptr <osg::Vec3Array> cubeVertexVector; if (! strcmp (cubeGeometry->getVertexArray()->className(), "Vec3Array")) { cubeVertexVector = (osg::Vec3Array *) cubeGeometry->getVertexArray(); } else { //handle the error however you want -- here all I do is print a warning and bail out. std::cerr << "Unexpected VertexArray className.\n" << std::endl; return; } osg::Vec3Array *array = new osg::Vec3Array(cubeVertexVector->size()); std::map <osg::Vec3, int> vertexMap; osg::Vec3 nextVertex; int j = 0; for (int i = 0; i < cubeVertexVector->size(); i++) { nextVertex = cubeVertexVector->at(i); if (j == 3) j = 0; if(vertexMap.find(nextVertex) == vertexMap.end()) {//check if it is the first, the second o the third vertex of the triangle and associate appropriate attribute if (j==0) { array->at(i) = (osg::Vec3(1.0,0.0,0.0)); vertexMap[nextVertex] = i; } else if (j==1) { array->at(i) = (osg::Vec3(0.0,1.0,0.0)); vertexMap[nextVertex] = i; } else if (j==2) { array->at(i) = (osg::Vec3(0.0,0.0,1.0)); vertexMap[nextVertex] = i; } } else { //std::cout<< "Vertex already present in the map at index "<< vertexMap[nextVertex] << std::endl; array->at(i) = osg::Vec3(array->at(vertexMap[nextVertex])); } j++; } if( !cubeGeometry->getVertexAttribArray( 31 ) ) { //cubeGeometry->setVertexAttribData(31, osg::Geometry::ArrayData(array,osg::Geometry::BIND_PER_VERTEX, GL_FALSE ) ); std::cout << "setting barycentric attr unit array of size " << array->getNumElements() << std::endl; cubeGeometry->setVertexAttribArray(31, array); cubeGeometry->setVertexAttribBinding(BARYCENTRIC_ATTR_UNIT, osg::Geometry::BIND_PER_VERTEX); } } } } } The attribute is binded to the program with the line of code Code: void OSGGraphicsUtils::loadShaders(osg::ref_ptr<osg::StateSet> &objectStateSet, const char *vsSource, const char *fsSource, osg::ref_ptr<osg::Node> object, const char *shaderName) { // set shader for mammoth osg::ref_ptr<osg::Program> shaderProgram = new osg::Program; shaderProgram->setName(shaderName); shaderProgram->addShader( new osg::Shader( osg::Shader::VERTEX, vsSource ) ); shaderProgram->addShader( new osg::Shader( osg::Shader::FRAGMENT, fsSource ) ); objectStateSet = object->getOrCreateStateSet(); objectStateSet->setAttributeAndModes(shaderProgram, osg::StateAttribute::ON ); if (strcmp(shaderName,"ShaderWireframe")==0) { std::cout << "adding barycentric coordinate attribute to the shader" << std::endl; shaderProgram->addBindAttribLocation("a_BaryCoord", 31); OSGGraphicsUtils::setBarycentricCoordinates(object.get(), shaderProgram.get()); } } This is the vertex shader Code: precision highp float; varying vec3 vBC; attribute vec3 a_BaryCoord; void main(void) { vBC = a_BaryCoord; gl_Position = ftransform(); } This is the fragment shader I use for testing. Code: precision highp float; varying vec3 vBC; void main (void) { gl_FragColor = vec4(vBC.r, vBC.g, vBC.b, 1.0); } In theory with a correct binding of the attribute I should obtain triangles with a red, a green and a blue vertex and the colors inside the triangle should interpolate based on these three vertices. All the triangles of the model should look like this http://www.arcsynthesis.org/gltut/Basics/VertexColors.png However the result is bizzarre and unexpected. As a matter of fact I have a cube with three black sides and one side red, one side green and one side blue. Can you help me, please? I feel I am near to the solution but I can't find the error! Thank you very much for your time, John [/code] ------------------ Read this topic online here: http://forum.openscenegraph.org/viewtopic.php?p=57059#57059 _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org