Actually I solved it... one of the problems was that the number I was using for 
the attribute was too big (or reserved).



I am forced to use OpenGL ES 2.0 because I develop on iOS platform! 

Thank you anyway for your advice.

Cheers,

John

This is the working code

Code:


#define BARYCENTRIC_ATTR_UNIT 11

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++)
    {
        //play with the Geode here
        std::cout << "Geode number " << j << std::endl;
        
        //get the current geode
        osg::Geode* currentGeode = listOfGeodes.at(j);
        
        if (currentGeode != NULL)
        {
            
            std::cout << "number of drawables in geode is " << 
currentGeode->getNumDrawables() << std::endl;
            
            for (int i = 0; i < currentGeode->getNumDrawables(); i++)
            {
                std::cout << "current geode class is "<< 
currentGeode->getDrawable(i)->className() << std::endl;

                std::cout << "inside cycle " << i << std::endl;
                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::ref_ptr<osg::Vec3Array> array = new osg::Vec3Array;
                                
                //add this to declaration section:
                std::map <int, int> vertexMap;

                osg::ref_ptr <osg::PrimitiveSet> nextPrimitiveSet;
                
                // ... //
                
                int k = 0;
                for (i = 0; i < cubeGeometry->getNumPrimitiveSets(); i++) {
                    nextPrimitiveSet = cubeGeometry->getPrimitiveSet(i);

                    //cout << "PrimitiveSet #" << i << " has Mode: " << 
nextPrimitiveSet->getMode() << endl;
                    //cout << "\tVertex Indices: " << endl;
                    
                    for (j = 0; j < nextPrimitiveSet->getNumIndices(); j++)
                    {
                        
                        if(vertexMap.find(nextPrimitiveSet->index(j)) == 
vertexMap.end())
                        {
                            if (k==3) k = 0;
                            
                            //cout << "\t" << nextPrimitiveSet->index(j) << 
endl;
                            
                            vertexMap[nextPrimitiveSet->index(j)] = k;
                            
                            k++;
                        }
                        else
                        {
                            k = vertexMap[nextPrimitiveSet->index(j)] + 1;
                        }
                    }
                }
                
                for (int i = 0; i < numAttribs; i++) {
                    
                    int j = vertexMap[i];
                    
                    if (j==0)
                    {
                        array->push_back(osg::Vec3f(1.0f,0.0f,0.0f));
                    }
                    else if (j==1)
                    {
                        array->push_back(osg::Vec3f(0.0f,1.0f,0.0f));
                        
                    }
                    else if (j==2)
                    {
                        array->push_back(osg::Vec3f(0.0f,0.0f,1.0f));
                    }
                    
                    //std::cout << "Vertex #" << i << ": ("<< 
cubeVertexVector->getName()<<"): (" << nextVertex[0] << ", " << nextVertex[1] 
<< ", " << nextVertex[2] << ")\n";
                }
                
                std::cout << "Array size is " <<array->getNumElements() << 
std::endl;

                if( !cubeGeometry->getVertexAttribArray( BARYCENTRIC_ATTR_UNIT 
) )
                {
                    //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(BARYCENTRIC_ATTR_UNIT, 
array.get());
                    cubeGeometry->setVertexAttribBinding(BARYCENTRIC_ATTR_UNIT, 
osg::Geometry::BIND_PER_VERTEX);
                }
                
                
            }
        }
    }
}





And this is the code to load the shaader on the object node. To work correctly 
the node should contain a 3d model loaded with the noTriStripPolygons option.


Code:

void OSGGraphicsUtils::loadShaders(osg::ref_ptr<osg::StateSet> &objectStateSet, 
const char *vsSource, const char *fsSource, osg::Node *object, const char 
*shaderName)
{
    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 (std::strlen(shaderName)>14 && 
std::string(shaderName,0,15)=="ShaderWireframe")
    {
        std::cout << "adding barycentric coordinate attribute to the shader" << 
std::endl;
        shaderProgram->addBindAttribLocation("a_BaryCoord", 
BARYCENTRIC_ATTR_UNIT);
        OSGGraphicsUtils::setBarycentricCoordinates(object, 
shaderProgram.get());
    }
}


[/code]

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=57116#57116





_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to