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

Reply via email to