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

Reply via email to