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
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org