123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711 |
- /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
- *
- * This library is open source and may be redistributed and/or modified under
- * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
- * (at your option) any later version. The full license is in LICENSE file
- * included with this distribution, and on the openscenegraph.org website.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * OpenSceneGraph Public License for more details.
- */
- #ifndef OSG_DRAWABLE
- #define OSG_DRAWABLE 1
- #include <osg/BoundingBox>
- #include <osg/Shape>
- #include <osg/BufferObject>
- #include <osg/PrimitiveSet>
- #include <osg/RenderInfo>
- #include <osg/Group>
- #ifndef GL_NV_occlusion_query
- #define GL_OCCLUSION_TEST_HP 0x8165
- #define GL_OCCLUSION_TEST_RESULT_HP 0x8166
- #define GL_PIXEL_COUNTER_BITS_NV 0x8864
- #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865
- #define GL_PIXEL_COUNT_NV 0x8866
- #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867
- #endif
- #ifndef GL_ARB_occlusion_query
- #define GL_SAMPLES_PASSED_ARB 0x8914
- #define GL_QUERY_COUNTER_BITS_ARB 0x8864
- #define GL_CURRENT_QUERY_ARB 0x8865
- #define GL_QUERY_RESULT_ARB 0x8866
- #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
- #endif
- #ifndef GL_TIME_ELAPSED
- #define GL_TIME_ELAPSED 0x88BF
- #define GL_TIMESTAMP 0x8E28
- #endif
- #ifndef GL_QUERY_RESULT
- #define GL_QUERY_RESULT 0x8866
- #define GL_QUERY_RESULT_AVAILABLE 0x8867
- #endif
- #define INLINE_DRAWABLE_DRAW
- namespace osg {
- class Vec2f;
- class Vec3f;
- class Vec4f;
- class Vec4ub;
- class Geometry;
- class NodeVisitor;
- class ArrayDispatchers;
- /** Pure virtual base class for drawable geometry. In OSG, everything that can
- * be rendered is implemented as a class derived from \c Drawable. The
- * \c Drawable class contains no drawing primitives, since these are provided
- * by subclasses such as \c osg::Geometry.
- * <p>Notice that a \c Drawable is not a \c Node, and therefore it cannot be
- * directly added to a scene graph. Instead, <tt>Drawable</tt>s are attached to
- * <tt>Geode</tt>s, which are scene graph nodes.
- * <p>The OpenGL state that must be used when rendering a \c Drawable is
- * represented by a \c StateSet. Since a \c Drawable has a reference
- * (\c osg::ref_ptr) to a \c StateSet, <tt>StateSet</tt>s can be shared between
- * different <tt>Drawable</tt>s. In fact, sharing <tt>StateSet</tt>s is a good
- * way to improve performance, since this allows OSG to reduce the number of
- * expensive changes in the OpenGL state.
- * <p>Finally, <tt>Drawable</tt>s can also be shared between different
- * <tt>Geode</tt>s, so that the same geometry (loaded to memory just once) can
- * be used in different parts of the scene graph.
- */
- class OSG_EXPORT Drawable : public Node
- {
- public:
- Drawable();
- /** Copy constructor using CopyOp to manage deep vs shallow copy.*/
- Drawable(const Drawable& drawable,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
- META_Node(osg, Drawable);
- /** Convert 'this' into a Drawable pointer if Object is a Drawable, otherwise return 0.
- * Equivalent to dynamic_cast<Drawable*>(this).*/
- virtual Drawable* asDrawable() { return this; }
- /** convert 'const this' into a const Drawable pointer if Object is a Drawable, otherwise return 0.
- * Equivalent to dynamic_cast<const Drawable*>(this).*/
- virtual const Drawable* asDrawable() const { return this; }
- /** Compute the DataVariance based on an assessment of callback etc.*/
- virtual void computeDataVariance();
- /** Get the list of matrices that transform this node from local coordinates to world coordinates.
- * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specified node. */
- MatrixList getWorldMatrices(const osg::Node* haltTraversalAtNode=0) const;
- /** Set the initial bounding volume to use when computing the overall bounding volume.*/
- void setInitialBound(const osg::BoundingBox& bbox) { _initialBoundingBox = bbox; dirtyBound(); }
- /** Set the initial bounding volume to use when computing the overall bounding volume.*/
- const BoundingBox& getInitialBound() const { return _initialBoundingBox; }
- inline const BoundingSphere& getBound() const
- {
- if(!_boundingSphereComputed) getBoundingBox();
- return _boundingSphere;
- }
- /** Get BoundingBox of Drawable.
- * If the BoundingBox is not up to date then its updated via an internal call to computeBond().
- */
- inline const BoundingBox& getBoundingBox() const
- {
- if(!_boundingSphereComputed)
- {
- _boundingBox = _initialBoundingBox;
- if (_computeBoundingBoxCallback.valid())
- _boundingBox.expandBy(_computeBoundingBoxCallback->computeBound(*this));
- else
- _boundingBox.expandBy(computeBoundingBox());
- if(_boundingBox.valid()){
- _boundingSphere.set(_boundingBox.center(), _boundingBox.radius());
- } else {
- _boundingSphere.init();
- }
- _boundingSphereComputed = true;
- }
- return _boundingBox;
- }
- /** Compute the bounding sphere around Drawables's geometry.*/
- virtual BoundingSphere computeBound() const;
- /** Compute the bounding box around Drawables's geometry.*/
- virtual BoundingBox computeBoundingBox() const;
- /** Callback to allow users to override the default computation of bounding volume. */
- struct ComputeBoundingBoxCallback : public osg::Object
- {
- ComputeBoundingBoxCallback() {}
- ComputeBoundingBoxCallback(const ComputeBoundingBoxCallback& org,const CopyOp& copyop):
- Object(org, copyop) {}
- META_Object(osg,ComputeBoundingBoxCallback);
- virtual BoundingBox computeBound(const osg::Drawable&) const { return BoundingBox(); }
- };
- /** Set the compute bound callback to override the default computeBound.*/
- void setComputeBoundingBoxCallback(ComputeBoundingBoxCallback* callback) { _computeBoundingBoxCallback = callback; }
- /** Get the compute bound callback.*/
- ComputeBoundingBoxCallback* getComputeBoundingBoxCallback() { return _computeBoundingBoxCallback.get(); }
- /** Get the const compute bound callback.*/
- const ComputeBoundingBoxCallback* getComputeBoundingBoxCallback() const { return _computeBoundingBoxCallback.get(); }
- /** Set the Shape of the \c Drawable. The shape can be used to
- * speed up collision detection or as a guide for procedural
- * geometry generation.
- * @see osg::Shape.
- */
- virtual void setShape(Shape* shape) { _shape = shape; }
- template<class T> void setShape(const ref_ptr<T>& shape) { setShape(shape.get()); }
- /** Get the Shape of the Drawable.*/
- inline Shape* getShape() { return _shape.get(); }
- /** Get the const Shape of the const Drawable.*/
- inline const Shape* getShape() const { return _shape.get(); }
- /** Set the drawable so that it can or cannot be used in conjunction with OpenGL
- * display lists. When set to true, calls to Drawable::setUseDisplayList,
- * whereas when set to false, no display lists can be created and calls
- * to setUseDisplayList are ignored, and a warning is produced. The latter
- * is typically used to guard against the switching on of display lists
- * on objects with dynamic internal data such as continuous Level of Detail
- * algorithms.*/
- void setSupportsDisplayList(bool flag);
- /** Get whether display lists are supported for this drawable instance.*/
- inline bool getSupportsDisplayList() const { return _supportsDisplayList; }
- /** When set to true, force the draw method to use OpenGL Display List for rendering.
- If false, rendering directly. If the display list has not been compiled
- already, the next call to draw will automatically create the display list.*/
- void setUseDisplayList(bool flag);
- /** Return whether OpenGL display lists are being used for rendering.*/
- inline bool getUseDisplayList() const { return _useDisplayList; }
- /** Return OpenGL display list for specified contextID. */
- inline GLuint& getDisplayList(unsigned int contextID) const { return _globjList[contextID]; }
- /** When set to true, ignore the setUseDisplayList() settings, and hints to the drawImplementation
- method to use OpenGL vertex buffer objects for rendering.*/
- virtual void setUseVertexBufferObjects(bool flag);
- /** Return whether OpenGL vertex buffer objects should be used when supported by OpenGL driver.*/
- inline bool getUseVertexBufferObjects() const { return _useVertexBufferObjects; }
- /** Set whether to use a local VertexArrayObject for this Drawable.*/
- void setUseVertexArrayObject(bool flag);
- /** Return whether to use a local VertexArrayObject for this Drawable.*/
- bool getUseVertexArrayObject() const { return _useVertexArrayObject; }
- #ifdef OSG_USE_DEPRECATED_API
- /** Deprecated, use dirtyGLObjects() instead. */
- inline void dirtyDisplayList()
- {
- dirtyGLObjects();
- }
- #endif
- /** Force a recompile on next draw() of any OpenGL objects associated with this geoset.*/
- virtual void dirtyGLObjects();
- /** Return the estimated size of GLObjects (display lists/vertex buffer objects) that are associated with this drawable.
- * This size is used a hint for reuse of deleted display lists/vertex buffer objects. */
- virtual unsigned int getGLObjectSizeHint() const { return 0; }
- /** Draw OpenGL primitives.
- * If the \c Drawable has \c _useDisplayList set to \c true, then use
- * an OpenGL display list, automatically compiling one if required.
- * Otherwise, call \c drawImplementation().
- * @note This method should \e not be overridden in subclasses, as it
- * manages the optional display list (notice this is not even
- * \c virtual). Subclasses should override
- * \c drawImplementation() instead.
- */
- #ifdef INLINE_DRAWABLE_DRAW
- inline void draw(RenderInfo& renderInfo) const;
- #else
- void draw(RenderInfo& renderInfo) const;
- #endif
- inline void drawInner(RenderInfo& renderInfo) const
- {
- if (_drawCallback.valid())
- _drawCallback->drawImplementation(renderInfo,this);
- else
- drawImplementation(renderInfo);
- }
- /** Immediately compile this \c Drawable into an OpenGL Display List/VertexBufferObjects.
- * @note Operation is ignored if \c _useDisplayList is \c false or VertexBufferObjects are not used.
- */
- virtual void compileGLObjects(RenderInfo& renderInfo) const;
- /** Callback class for overriding the default Drawable::createCreateVertexArrayStateImplementation().*/
- struct CreateVertexArrayStateCallback : public virtual osg::Object
- {
- CreateVertexArrayStateCallback() {}
- CreateVertexArrayStateCallback(const CreateVertexArrayStateCallback& rhs,const CopyOp& copyop):
- Object(rhs, copyop) {}
- META_Object(osg, CreateVertexArrayStateCallback);
- /** do customized createVertexArrayState .*/
- virtual osg::VertexArrayState* createVertexArrayStateImplementation(osg::RenderInfo& renderInfo, const osg::Drawable* drawable) const
- {
- return drawable->createVertexArrayStateImplementation(renderInfo);
- }
- };
- /** Set the callback to override the default Drawable::createCreateVertexArrayStateImplementation().*/
- void setCreateVertexArrayStateCallback(CreateVertexArrayStateCallback* cb) { _createVertexArrayStateCallback = cb; }
- /** Get the callback that overrides the default Drawable::createCreateVertexArrayStateImplementation().*/
- CreateVertexArrayStateCallback* getCreateVertexArrayStateCallback() { return _createVertexArrayStateCallback.get(); }
- /** Get the const callback that overrides the default Drawable::createCreateVertexArrayStateImplementation().*/
- const CreateVertexArrayStateCallback* getCreateVertexArrayStateCallback() const { return _createVertexArrayStateCallback.get(); }
- /** Create the VertexArrayState object used to track vertex array and vertex array object state. This method will be called automatically during rendering setup so users should not call this themselves.*/
- inline VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const
- {
- if (_createVertexArrayStateCallback.valid()) return _createVertexArrayStateCallback->createVertexArrayStateImplementation(renderInfo, this);
- else return createVertexArrayStateImplementation(renderInfo);
- }
- /** Implementation of Create the VertexArrayState object.*/
- virtual VertexArrayState* createVertexArrayStateImplementation(RenderInfo& renderInfo) const;
- void setVertexArrayStateList(VertexArrayStateList& vasl) { _vertexArrayStateList = vasl; }
- VertexArrayStateList& getVertexArrayStateList() { return _vertexArrayStateList; }
- const VertexArrayStateList& getVertexArrayStateList() const { return _vertexArrayStateList; }
- /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/
- virtual void setThreadSafeRefUnref(bool threadSafe);
- /** Resize any per context GLObject buffers to specified size. */
- virtual void resizeGLObjectBuffers(unsigned int maxSize);
- /** If State is non-zero, this function releases OpenGL objects for
- * the specified graphics context. Otherwise, releases OpenGL objects
- * for all graphics contexts. */
- virtual void releaseGLObjects(State* state=0) const;
- // for backwards compatibility as local implementations are now found in osg namespace within the include/osg/Callback header
- typedef DrawableUpdateCallback UpdateCallback;
- typedef DrawableEventCallback EventCallback;
- typedef DrawableCullCallback CullCallback;
- /** Callback attached to an Drawable which allows the users to customize the drawing of an exist Drawable object.
- * The draw callback is implement as a replacement to the Drawable's own drawImplementation() method, if the
- * the user intends to decorate the existing draw code then simple call the drawable->drawImplementation() from
- * with the callbacks drawImplementation() method. This allows the users to do both pre and post callbacks
- * without fuss and can even disable the inner draw if required.*/
- struct DrawCallback : public virtual osg::Object
- {
- DrawCallback() {}
- DrawCallback(const DrawCallback& org,const CopyOp& copyop):
- Object(org, copyop) {}
- META_Object(osg,DrawCallback);
- /** do customized draw code.*/
- virtual void drawImplementation(osg::RenderInfo& /*renderInfo*/,const osg::Drawable* /*drawable*/) const {}
- };
- /** Set the DrawCallback which allows users to attach customize the drawing of existing Drawable object.*/
- virtual void setDrawCallback(DrawCallback* dc) { _drawCallback=dc; dirtyGLObjects(); }
- /** Get the non const DrawCallback.*/
- DrawCallback* getDrawCallback() { return _drawCallback.get(); }
- /** Get the const DrawCallback.*/
- const DrawCallback* getDrawCallback() const { return _drawCallback.get(); }
- /** drawImplementation(RenderInfo&) is a pure virtual method for the actual implementation of OpenGL drawing calls, such as vertex arrays and primitives, that
- * must be implemented in concrete subclasses of the Drawable base class, examples include osg::Geometry and osg::ShapeDrawable.
- * drawImplementation(RenderInfo&) is called from the draw(RenderInfo&) method, with the draw method handling management of OpenGL display lists,
- * and drawImplementation(RenderInfo&) handling the actual drawing itself.
- * renderInfo : The osg::RenderInfo object that encapsulates the current rendering information including the osg::State OpenGL state for the current graphics context. */
- virtual void drawImplementation(RenderInfo& /*renderInfo*/) const {}
- /** Return a OpenGL display list handle a newly generated or reused from display list cache. */
- static GLuint generateDisplayList(unsigned int contextID, unsigned int sizeHint = 0);
- /** Use deleteDisplayList instead of glDeleteList to allow
- * OpenGL display list to be cached until they can be deleted
- * by the OpenGL context in which they were created, specified
- * by contextID.*/
- static void deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint = 0);
- /** Set the minimum number of display lists to retain in the deleted display list cache. */
- static void setMinimumNumberOfDisplayListsToRetainInCache(unsigned int minimum);
- /** Get the minimum number of display lists to retain in the deleted display list cache. */
- static unsigned int getMinimumNumberOfDisplayListsToRetainInCache();
- typedef unsigned int AttributeType;
- enum AttributeTypes
- {
- VERTICES = 0,
- WEIGHTS = 1,
- NORMALS = 2,
- COLORS = 3,
- SECONDARY_COLORS = 4,
- FOG_COORDS = 5,
- ATTRIBUTE_6 = 6,
- ATTRIBUTE_7 = 7,
- TEXTURE_COORDS = 8,
- TEXTURE_COORDS_0 = TEXTURE_COORDS,
- TEXTURE_COORDS_1 = TEXTURE_COORDS_0+1,
- TEXTURE_COORDS_2 = TEXTURE_COORDS_0+2,
- TEXTURE_COORDS_3 = TEXTURE_COORDS_0+3,
- TEXTURE_COORDS_4 = TEXTURE_COORDS_0+4,
- TEXTURE_COORDS_5 = TEXTURE_COORDS_0+5,
- TEXTURE_COORDS_6 = TEXTURE_COORDS_0+6,
- TEXTURE_COORDS_7 = TEXTURE_COORDS_0+7
- // only eight texture coord examples provided here, but underlying code can handle any no of texture units,
- // simply co them as (TEXTURE_COORDS_0+unit).
- };
- class AttributeFunctor
- {
- public:
- virtual ~AttributeFunctor() {}
- virtual void apply(AttributeType,unsigned int,GLbyte*) {}
- virtual void apply(AttributeType,unsigned int,GLshort*) {}
- virtual void apply(AttributeType,unsigned int,GLint*) {}
- virtual void apply(AttributeType,unsigned int,GLubyte*) {}
- virtual void apply(AttributeType,unsigned int,GLushort*) {}
- virtual void apply(AttributeType,unsigned int,GLuint*) {}
- virtual void apply(AttributeType,unsigned int,float*) {}
- virtual void apply(AttributeType,unsigned int,Vec2*) {}
- virtual void apply(AttributeType,unsigned int,Vec3*) {}
- virtual void apply(AttributeType,unsigned int,Vec4*) {}
- virtual void apply(AttributeType,unsigned int,Vec4ub*) {}
- virtual void apply(AttributeType,unsigned int,double*) {}
- virtual void apply(AttributeType,unsigned int,Vec2d*) {}
- virtual void apply(AttributeType,unsigned int,Vec3d*) {}
- virtual void apply(AttributeType,unsigned int,Vec4d*) {}
- };
- /** Return true if the Drawable subclass supports accept(AttributeFunctor&).*/
- virtual bool supports(const AttributeFunctor&) const { return false; }
- /** accept an AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has.
- * return true if functor handled by drawable,
- * return false on failure of drawable to generate functor calls.*/
- virtual void accept(AttributeFunctor&) {}
- class ConstAttributeFunctor
- {
- public:
- virtual ~ConstAttributeFunctor() {}
- virtual void apply(AttributeType,unsigned int,const GLbyte*) {}
- virtual void apply(AttributeType,unsigned int,const GLshort*) {}
- virtual void apply(AttributeType,unsigned int,const GLint*) {}
- virtual void apply(AttributeType,unsigned int,const GLubyte*) {}
- virtual void apply(AttributeType,unsigned int,const GLushort*) {}
- virtual void apply(AttributeType,unsigned int,const GLuint*) {}
- virtual void apply(AttributeType,unsigned int,const float*) {}
- virtual void apply(AttributeType,unsigned int,const Vec2*) {}
- virtual void apply(AttributeType,unsigned int,const Vec3*) {}
- virtual void apply(AttributeType,unsigned int,const Vec4*) {}
- virtual void apply(AttributeType,unsigned int,const Vec4ub*) {}
- virtual void apply(AttributeType,unsigned int,const double*) {}
- virtual void apply(AttributeType,unsigned int,const Vec2d*) {}
- virtual void apply(AttributeType,unsigned int,const Vec3d*) {}
- virtual void apply(AttributeType,unsigned int,const Vec4d*) {}
- };
- /** Return true if the Drawable subclass supports accept(ConstAttributeFunctor&).*/
- virtual bool supports(const ConstAttributeFunctor&) const { return false; }
- /** Accept an AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has.
- * return true if functor handled by drawable,
- * return false on failure of drawable to generate functor calls.*/
- virtual void accept(ConstAttributeFunctor&) const {}
- /** Return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/
- virtual bool supports(const PrimitiveFunctor&) const { return false; }
- /** Accept a PrimitiveFunctor and call its methods to tell it about the internal primitives that this Drawable has.
- * return true if functor handled by drawable, return false on failure of drawable to generate functor calls.
- * Note, PrimitiveFunctor only provides const access of the primitives, as primitives may be procedurally generated
- * so one cannot modify it.*/
- virtual void accept(PrimitiveFunctor&) const {}
- /** Return true if the Drawable subclass supports accept(PrimitiveIndexFunctor&).*/
- virtual bool supports(const PrimitiveIndexFunctor&) const { return false; }
- /** Accept a PrimitiveIndexFunctor and call its methods to tell it about the internal primitives that this Drawable has.
- * return true if functor handled by drawable, return false on failure of drawable to generate functor calls.
- * Note, PrimitiveIndexFunctor only provide const access of the primitives, as primitives may be procedurally generated
- * so one cannot modify it.*/
- virtual void accept(PrimitiveIndexFunctor&) const {}
- protected:
- Drawable& operator = (const Drawable&) { return *this;}
- virtual ~Drawable();
- /** set the bounding box .*/
- void setBound(const BoundingBox& bb) const;
- friend class Node;
- friend class Geode;
- friend class StateSet;
- BoundingBox _initialBoundingBox;
- ref_ptr<ComputeBoundingBoxCallback> _computeBoundingBoxCallback;
- mutable BoundingBox _boundingBox;
- ref_ptr<Shape> _shape;
- bool _supportsDisplayList;
- bool _useDisplayList;
- bool _supportsVertexBufferObjects;
- bool _useVertexBufferObjects;
- bool _useVertexArrayObject;
- typedef osg::buffered_value<GLuint> GLObjectList;
- mutable GLObjectList _globjList;
- mutable VertexArrayStateList _vertexArrayStateList;
- ref_ptr<DrawCallback> _drawCallback;
- ref_ptr<CreateVertexArrayStateCallback> _createVertexArrayStateCallback;
- };
- #ifdef INLINE_DRAWABLE_DRAW
- inline void Drawable::draw(RenderInfo& renderInfo) const
- {
- State& state = *renderInfo.getState();
- bool useVertexArrayObject = state.useVertexArrayObject(_useVertexArrayObject);
- if (useVertexArrayObject)
- {
- unsigned int contextID = renderInfo.getContextID();
- VertexArrayState* vas = _vertexArrayStateList[contextID].get();
- if (!vas)
- {
- _vertexArrayStateList[contextID] = vas = createVertexArrayState(renderInfo);
- }
- else
- {
- // vas->setRequiresSetArrays(getDataVariance()==osg::Object::DYNAMIC);
- }
- State::SetCurrentVertexArrayStateProxy setVASProxy(state, vas);
- state.bindVertexArrayObject(vas);
- drawInner(renderInfo);
- vas->setRequiresSetArrays(getDataVariance()==osg::Object::DYNAMIC);
- return;
- }
- // TODO, add check against whether VAO is active and supported
- if (state.getCurrentVertexArrayState())
- {
- //OSG_NOTICE<<"state.getCurrentVertexArrayState()->getVertexArrayObject()="<< state.getCurrentVertexArrayState()->getVertexArrayObject()<<std::endl;
- state.bindVertexArrayObject(state.getCurrentVertexArrayState());
- }
- #ifdef OSG_GL_DISPLAYLISTS_AVAILABLE
- if (!state.useVertexBufferObject(_supportsVertexBufferObjects && _useVertexBufferObjects) && _useDisplayList)
- {
- // get the contextID (user defined ID of 0 upwards) for the
- // current OpenGL context.
- unsigned int contextID = renderInfo.getContextID();
- // get the globj for the current contextID.
- GLuint& globj = _globjList[contextID];
- if( globj == 0 )
- {
- // compile the display list
- globj = generateDisplayList(contextID, getGLObjectSizeHint());
- glNewList( globj, GL_COMPILE );
- drawInner(renderInfo);
- glEndList();
- }
- // call the display list
- glCallList( globj);
- }
- else
- #endif
- {
- // if state.previousVertexArrayState() is different than currentVertexArrayState bind current
- // OSG_NOTICE<<"Fallback drawInner()........................"<<std::endl;
- drawInner(renderInfo);
- }
- }
- #endif
- class AttributeFunctorArrayVisitor : public ArrayVisitor
- {
- public:
- AttributeFunctorArrayVisitor(Drawable::AttributeFunctor& af):
- _af(af),
- _type(0) {}
- virtual ~AttributeFunctorArrayVisitor() {}
- virtual void apply(ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec4ubArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(DoubleArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec2dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec3dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(Vec4dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- inline void applyArray(Drawable::AttributeType type,Array* array)
- {
- if (array)
- {
- _type = type;
- array->accept(*this);
- }
- }
- protected:
- AttributeFunctorArrayVisitor& operator = (const AttributeFunctorArrayVisitor&) { return *this; }
- Drawable::AttributeFunctor& _af;
- Drawable::AttributeType _type;
- };
- class ConstAttributeFunctorArrayVisitor : public ConstArrayVisitor
- {
- public:
- ConstAttributeFunctorArrayVisitor(Drawable::ConstAttributeFunctor& af):
- _af(af),
- _type(0) {}
- virtual ~ConstAttributeFunctorArrayVisitor() {}
- virtual void apply(const ByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const ShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const IntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const UByteArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const UShortArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const UIntArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec4ubArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const FloatArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec2Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec3Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec4Array& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const DoubleArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec2dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec3dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- virtual void apply(const Vec4dArray& array) { if (!array.empty()) _af.apply(_type,array.size(),&(array.front())); }
- inline void applyArray(Drawable::AttributeType type,const Array* array)
- {
- if (array)
- {
- _type = type;
- array->accept(*this);
- }
- }
- protected:
- ConstAttributeFunctorArrayVisitor& operator = (const ConstAttributeFunctorArrayVisitor&) { return *this; }
- Drawable::ConstAttributeFunctor& _af;
- Drawable::AttributeType _type;
- };
- }
- #endif
|