example of drawElementsUShort with primitive restart
class DrawElementsUShortRestart: public osg::DrawElementsUShort
{
public:
DrawElementsUShortRestart(const osg::DrawElementsUShort&);
DrawElementsUShortRestart(GLenum mode=GL_TRIANGLE_STRIP):
osg::DrawElementsUShort(mode), _enabled(false), _index(USHRT_MAX)
{}
DrawElementsUShortRestart(std::vector<osg::DrawElementsUShort*>);
DrawElementsUShortRestart(GLenum mode, unsigned int no, const GLushort*
ptr, int numInstances=0) :
DrawElementsUShort(mode,no,ptr,numInstances), _enabled(false),
_index(USHRT_MAX)
{}
void draw(osg::State& state, bool useVertexBufferObjects) const;
void setRestartIndex(unsigned index)
{
_index = index;
}
int getRestartIndex()
{
if (_enabled) return -1;
return _index;
}
private:
void glPrimitiveRestartIndexNV(GLuint index, unsigned contextID) const
{
std::map<unsigned, PrimitiveRestartIndexNV>::iterator itr =
_map.find(contextID);
if (itr==_map.end())
{
PrimitiveRestartIndexNV ptr = 0;
osg::setGLExtensionFuncPtr(ptr,
"glPrimitiveRestartIndexNV" );
if (!ptr) throw
std::runtime_error("glPrimitiveRestartIndexNV is not supported or smth");
_map[contextID] = ptr;
ptr(index);
}
else
itr->second(index);
};
typedef void (APIENTRY * PrimitiveRestartIndexNV)(GLuint);
static std::map<unsigned, PrimitiveRestartIndexNV> _map;
bool _enabled;
GLushort _index;
};
DrawElementsUShortRestart::DrawElementsUShortRestart(std::vector<osg::DrawElementsUShort*>
vec)
:DrawElementsUShort(GL_TRIANGLE_STRIP), _enabled(true), _index(USHRT_MAX-1)
{
for (unsigned i = 0; i< vec.size(); i++)
{
for (unsigned j = 0; j< vec[i]->getNumIndices(); j++)
{
addElement(vec[i]->getElement(j));
}
if (i < vec.size() - 1)
addElement(_index);
}
};
void DrawElementsUShortRestart::draw(osg::State& state, bool
useVertexBufferObjects) const
{
if (_enabled)
{
glEnableClientState(GL_PRIMITIVE_RESTART_NV);
glPrimitiveRestartIndexNV(_index, state.getContextID());
}
osg::DrawElementsUShort::draw(state, useVertexBufferObjects);
if (_enabled)
glDisableClientState(GL_PRIMITIVE_RESTART_NV);
};
std::map<unsigned, DrawElementsUShortRestart::PrimitiveRestartIndexNV>
DrawElementsUShortRestart::_map;
//i used this visitor to "merge" short primitivesets with triangle strips into
one large with primitive restart
class MakeDrawElementsRestartVisitor: public osg::NodeVisitor
{
public:
MakeDrawElementsRestartVisitor():osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN)
{
setNodeMaskOverride(~0x0);
}
using osg::NodeVisitor::apply;
void apply(osg::Geode& node)
{
std::cerr<<"node.getNumDrawables():"<<node.getNumDrawables()<<std::endl;
for (unsigned i = 0; i < node.getNumDrawables(); i++)
{
osg::Geometry* geom = node.getDrawable(i)->asGeometry();
std::vector<osg::DrawElementsUShort*> vec;
std::cerr<<"geom->getNumPrimitiveSets():"<<geom->getNumPrimitiveSets()<<std::endl;
if (geom->getNumPrimitiveSets()==1)
{
DrawElementsUShortRestart* deusr = new
DrawElementsUShortRestart();
}
for (unsigned j = 0; j < geom->getNumPrimitiveSets();
j++)
{
osg::PrimitiveSet* ps =
geom->getPrimitiveSet(j);
osg::DrawElementsUShort* deus =
dynamic_cast<osg::DrawElementsUShort*>(ps);
if (!deus)
{
std::cerr<<"return on
(!deus)"<<std::endl;
return;
}
if (ps->getMode()!=GL_TRIANGLE_STRIP)
{
std::cerr<<"return on ps->getMode() is
not GL_TRIANGLE_STRIP"<<std::endl;
return;
}
vec.push_back(deus);
}
DrawElementsUShortRestart* deusr = new
DrawElementsUShortRestart(vec);
geom->removePrimitiveSet(0,
geom->getNumPrimitiveSets());
geom->addPrimitiveSet(deusr);
std::cerr<<geom->getNumPrimitiveSets()<<std::endl;
std::cerr<<"changed"<<std::endl;
}
}
};
It may be possible to use stateset::setMode(..) instead of
glDisableClientState(GL_PRIMITIVE_RESTART_NV)\glEnableClientState(GL_PRIMITIVE_RESTART_NV).
I cant guarantee this code doesnt contain any major errors, but it worked for
me :D
Cheers,
Sergey.
05.08.2011, 15:50, "Peter Wrobel" <[email protected]>:
> Hi,
>
> Would it be possible for you to share you're implementation ? For me it is
> still not clear how to extend osg ( as you see on my question above ).
> I found this thread:
> http://www.mail-archive.com/[email protected]/msg46962.html
>
> Sergey ( @hybr, is this you ? ) has created a new extension class: class
> MyExtensions: public osg::Referenced
> wher he adds all possible extensions. I just wonder if this is the right way,
> or if one should not just be able to add the particular extension required to
> add a custom Drawable and or StateAttribute.
>
> Its really hard to find any documentation on that part of osg. Community, it
> would be very nice if somebody could create a simple explanatory example,
> please.
>
> Thank you!
>
> Cheers, ParticlePeter
>
> ------------------
> Read this topic online here:
> http://forum.openscenegraph.org/viewtopic.php?p=41878#41878
>
> _______________________________________________
> osg-users mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org
_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org