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" <particlepe...@gmx.de>: > 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/osg-users@lists.openscenegraph.org/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 > osg-users@lists.openscenegraph.org > http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org _______________________________________________ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org