785 lines
34 KiB
C++
785 lines
34 KiB
C++
/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2003 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/State>
|
|
#include <osg/NodeVisitor>
|
|
#include <osg/Shape>
|
|
#include <osg/buffered_value>
|
|
|
|
namespace osg {
|
|
|
|
class Vec2f;
|
|
class Vec3f;
|
|
class Vec4f;
|
|
class UByte4;
|
|
class Geometry;
|
|
|
|
#ifndef GL_ARB_vertex_buffer_object
|
|
|
|
// for compatibility with gl.h headers that don't support VBO,
|
|
#if defined(_WIN64)
|
|
typedef __int64 GLintptrARB;
|
|
typedef __int64 GLsizeiptrARB;
|
|
#elif defined(__ia64__) || defined(__x86_64__)
|
|
typedef long int GLintptrARB;
|
|
typedef long int GLsizeiptrARB;
|
|
#else
|
|
typedef int GLintptrARB;
|
|
typedef int GLsizeiptrARB;
|
|
#endif
|
|
|
|
#define GL_ARRAY_BUFFER_ARB 0x8892
|
|
#define GL_ELEMENT_ARRAY_BUFFER_ARB 0x8893
|
|
#define GL_ARRAY_BUFFER_BINDING_ARB 0x8894
|
|
#define GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB 0x8895
|
|
#define GL_VERTEX_ARRAY_BUFFER_BINDING_ARB 0x8896
|
|
#define GL_NORMAL_ARRAY_BUFFER_BINDING_ARB 0x8897
|
|
#define GL_COLOR_ARRAY_BUFFER_BINDING_ARB 0x8898
|
|
#define GL_INDEX_ARRAY_BUFFER_BINDING_ARB 0x8899
|
|
#define GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB 0x889A
|
|
#define GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB 0x889B
|
|
#define GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB 0x889C
|
|
#define GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB 0x889D
|
|
#define GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB 0x889E
|
|
#define GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB 0x889F
|
|
#define GL_STREAM_DRAW_ARB 0x88E0
|
|
#define GL_STREAM_READ_ARB 0x88E1
|
|
#define GL_STREAM_COPY_ARB 0x88E2
|
|
#define GL_STATIC_DRAW_ARB 0x88E4
|
|
#define GL_STATIC_READ_ARB 0x88E5
|
|
#define GL_STATIC_COPY_ARB 0x88E6
|
|
#define GL_DYNAMIC_DRAW_ARB 0x88E8
|
|
#define GL_DYNAMIC_READ_ARB 0x88E9
|
|
#define GL_DYNAMIC_COPY_ARB 0x88EA
|
|
#define GL_READ_ONLY_ARB 0x88B8
|
|
#define GL_WRITE_ONLY_ARB 0x88B9
|
|
#define GL_READ_WRITE_ARB 0x88BA
|
|
#define GL_BUFFER_SIZE_ARB 0x8764
|
|
#define GL_BUFFER_USAGE_ARB 0x8765
|
|
#define GL_BUFFER_ACCESS_ARB 0x88BB
|
|
#define GL_BUFFER_MAPPED_ARB 0x88BC
|
|
#define GL_BUFFER_MAP_POINTER_ARB 0x88BD
|
|
|
|
#endif
|
|
|
|
#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
|
|
|
|
// this is define to alter the way display lists are compiled inside the
|
|
// the draw method, it has been found that the NVidia drivers fail completely
|
|
// to optimize COMPILE_AND_EXECUTE in fact make it go slower than for no display
|
|
// lists, but optimize a separate COMPILE very well?! Define it as default
|
|
// the use of a sperate COMPILE, then glCallList rather than use COMPILE_AND_EXECUTE.
|
|
|
|
#define USE_SEPARATE_COMPILE_AND_EXECUTE
|
|
|
|
/** Pure virtual base class for drawable Geometry. Contains no drawing primitives
|
|
directly, these are provided by subclasses such as osg::Geometry. State attributes
|
|
for a Drawable are maintained in StateSet which the Drawable maintains
|
|
a referenced counted pointer to. Both Drawable's and StateSet's can
|
|
be shared for optimal memory usage and graphics performance.
|
|
*/
|
|
class SG_EXPORT Drawable : public Object
|
|
{
|
|
public:
|
|
|
|
Drawable();
|
|
|
|
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
|
|
Drawable(const Drawable& drawable,const CopyOp& copyop=CopyOp::SHALLOW_COPY);
|
|
|
|
virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Drawable*>(obj)!=NULL; }
|
|
virtual const char* libraryName() const { return "osg"; }
|
|
virtual const char* className() const { return "Drawable"; }
|
|
|
|
/** convert 'this' into a Geometry pointer if Drawable is a Geometry, otherwise return 0.
|
|
* Equivalent to dynamic_cast<Geometry*>(this).*/
|
|
virtual Geometry* asGeometry() { return 0; }
|
|
/** convert 'const this' into a const Geometry pointer if Drawable is a Geometry, otherwise return 0.
|
|
* Equivalent to dynamic_cast<const Geometry*>(this).*/
|
|
virtual const Geometry* asGeometry() const { return 0; }
|
|
|
|
|
|
/** A vector of osg::Node pointers which is used to store the parent(s) of drawable.*/
|
|
typedef std::vector<Node*> ParentList;
|
|
|
|
/** Get the parent list of drawable. */
|
|
inline const ParentList& getParents() const { return _parents; }
|
|
|
|
/** Get the a copy of parent list of node. A copy is returned to
|
|
* prevent modification of the parent list.*/
|
|
inline ParentList getParents() { return _parents; }
|
|
|
|
/** Get a single parent of Drawable.
|
|
* @param i index of the parent to get.
|
|
* @return the parent i.
|
|
*/
|
|
inline Node* getParent(unsigned int i) { return _parents[i]; }
|
|
/** Get a single const parent of Drawable.
|
|
* @param i index of the parent to get.
|
|
* @return the parent i.
|
|
*/
|
|
inline const Node* getParent(unsigned int i) const { return _parents[i]; }
|
|
|
|
/**
|
|
* Get the number of parents of node.
|
|
* @return the number of parents of this node.
|
|
*/
|
|
inline unsigned int getNumParents() const { return _parents.size(); }
|
|
|
|
|
|
|
|
/** Set the StateSet attached to the Drawable.
|
|
Previously attached StateSet are automatically unreferenced on
|
|
assignment of a new drawstate.*/
|
|
inline void setStateSet(StateSet *state) { _stateset = state; }
|
|
|
|
/** Get the attached StateSet.*/
|
|
inline StateSet* getStateSet() { return _stateset.get();}
|
|
|
|
/** Get the attached const StateSet.*/
|
|
inline const StateSet* getStateSet() const { return _stateset.get();}
|
|
|
|
/** Get the attached const StateSet,
|
|
* if one is not already attach create one,
|
|
* attach it to the drawable and return a pointer to it.*/
|
|
StateSet* getOrCreateStateSet();
|
|
|
|
|
|
/** Dirty the bounding box, forcing a computeBound() on the next call
|
|
* to getBound(). Should be called in the internal geometry of the Drawable
|
|
* is modified.*/
|
|
void dirtyBound();
|
|
|
|
/** get bounding box of geoset.
|
|
* Note, now made virtual to make it possible to implement user-drawn
|
|
* objects albeit so what crudely, to be improved later.
|
|
*/
|
|
inline const BoundingBox& getBound() const
|
|
{
|
|
if( !_bbox_computed)
|
|
computeBound();
|
|
return _bbox;
|
|
}
|
|
|
|
|
|
/** Set the Shape of the drawable. The shape can be used to
|
|
* speed up collision detection or as a guide for produral
|
|
* geometry generation - see osg::ProduralGeometry.*/
|
|
inline void setShape(Shape* shape) { _shape = shape; }
|
|
|
|
/** 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 to it can or cannot be used in conjunction with OpenGL
|
|
* display lists. With 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 later
|
|
* 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 already
|
|
compile 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; }
|
|
|
|
/** When set to true, ignore the setUseDisplayList() settings, and hints to the drawImplemention
|
|
method to use OpenGL vertex buffer objects for rendering..*/
|
|
void setUseVertexBufferObjects(bool flag);
|
|
|
|
/** Return whether OpenGL vertex buffer objects should be used when supported by OpenGL driver.*/
|
|
inline bool getUseVertexBufferObjects() const { return _useVertexBufferObjects; }
|
|
|
|
|
|
/** Force a recompile on next draw() of any OpenGL display list associated with this geoset.*/
|
|
void dirtyDisplayList();
|
|
|
|
|
|
|
|
/** draw OpenGL primitives.
|
|
* If the drawable has _useDisplayList set to true then use an OpenGL display
|
|
* list, automatically compiling one if required.
|
|
* Otherwise call drawImplementation().
|
|
* Note, draw method should *not* be overridden in subclasses as it
|
|
* manages the optional display list.
|
|
*/
|
|
inline void draw(State& state) const;
|
|
|
|
/** Immediately compile this drawable into an OpenGL Display List.
|
|
Note I, operation is ignored if _useDisplayList to false.
|
|
Note II, compile is not intended to be overridden in subclasses.*/
|
|
virtual void compile(State& state) const;
|
|
|
|
|
|
struct UpdateCallback : public virtual osg::Object
|
|
{
|
|
UpdateCallback() {}
|
|
|
|
UpdateCallback(const UpdateCallback&,const CopyOp&) {}
|
|
|
|
META_Object(osg,UpdateCallback)
|
|
|
|
/** do customized update code.*/
|
|
virtual void update(osg::NodeVisitor*, osg::Drawable*) {}
|
|
};
|
|
|
|
/** Set the UpdateCallback which allows users to attach customize the undating of an object during the update traversal.*/
|
|
void setUpdateCallback(UpdateCallback* ac);
|
|
|
|
/** Get the non const UpdateCallback.*/
|
|
UpdateCallback* getUpdateCallback() { return _updateCallback.get(); }
|
|
|
|
/** Get the const UpdateCallback.*/
|
|
const UpdateCallback* getUpdateCallback() const { return _updateCallback.get(); }
|
|
|
|
|
|
struct CullCallback : public virtual osg::Object
|
|
{
|
|
CullCallback() {}
|
|
|
|
CullCallback(const CullCallback&,const CopyOp&) {}
|
|
|
|
META_Object(osg,CullCallback)
|
|
|
|
/** do customized cull code, return true if drawable should be culled.*/
|
|
virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const { return false; }
|
|
};
|
|
|
|
/** Set the CullCallback which allows users to attach customize the culling of Drawable during the cull traversal.*/
|
|
void setCullCallback(CullCallback* cc) { _cullCallback=cc; }
|
|
|
|
/** Get the non const CullCallback.*/
|
|
CullCallback* getCullCallback() { return _cullCallback.get(); }
|
|
|
|
/** Get the const CullCallback.*/
|
|
const CullCallback* getCullCallback() const { return _cullCallback.get(); }
|
|
|
|
|
|
|
|
|
|
/** 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 exist 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 diable the inner draw in required.*/
|
|
struct DrawCallback : public virtual osg::Object
|
|
{
|
|
DrawCallback() {}
|
|
|
|
DrawCallback(const DrawCallback&,const CopyOp&) {}
|
|
|
|
META_Object(osg,DrawCallback)
|
|
|
|
/** do customized draw code.*/
|
|
virtual void drawImplementation(osg::State&,const osg::Drawable*) const {}
|
|
};
|
|
|
|
/** Set the DrawCallback which allows users to attach customize the drawing of existing Drawable object.*/
|
|
void setDrawCallback(DrawCallback* dc) { _drawCallback=dc; dirtyDisplayList(); }
|
|
|
|
/** Get the non const DrawCallback.*/
|
|
DrawCallback* getDrawCallback() { return _drawCallback.get(); }
|
|
|
|
/** Get the const DrawCallback.*/
|
|
const DrawCallback* getDrawCallback() const { return _drawCallback.get(); }
|
|
|
|
|
|
|
|
/** draw directly ignoring an OpenGL display list which could be attached.
|
|
* This is the internal draw method which does the drawing itself,
|
|
* and is the method to override when deriving from Drawable.
|
|
*/
|
|
virtual void drawImplementation(State& state) const = 0;
|
|
|
|
|
|
|
|
/** use deleteDisplayList instead of glDeleteList to allow
|
|
* OpenGL display list to 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);
|
|
|
|
/** flush all the cached display list which need to be deleted
|
|
* in the OpenGL context related to contextID.*/
|
|
static void flushDeletedDisplayLists(unsigned int contextID,double currentTime, double& availableTime);
|
|
|
|
/** use deleteVertexBufferObject instead of glDeleteList to allow
|
|
* OpenGL buffer objects to cached until they can be deleted
|
|
* by the OpenGL context in which they were created, specified
|
|
* by contextID.*/
|
|
static void deleteVertexBufferObject(unsigned int contextID,GLuint globj);
|
|
|
|
/** flush all the cached vertex buffer objects which need to be deleted
|
|
* in the OpenGL context related to contextID.*/
|
|
static void flushDeletedVertexBufferObjects(unsigned int contextID,double currentTime, double& availableTime);
|
|
|
|
typedef unsigned int AttributeType;
|
|
|
|
enum AttributeTypes
|
|
{
|
|
VERTICES = 0,
|
|
WEIGHTS = 1,
|
|
NORMALS = 2,
|
|
COLORS = 3,
|
|
SECONDARY_COLORS = 4,
|
|
FOG_COORDS = 5,
|
|
ATTIBUTE_6 = 6,
|
|
ATTIBUTE_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 texure 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,UByte4*) {}
|
|
};
|
|
|
|
|
|
/** return true if the Drawable subclass supports accept(AttributeFunctor&).*/
|
|
virtual bool supports(AttributeFunctor&) const { return false; }
|
|
|
|
/** accept an AttributeFunctor and call its methods to tell it about the interal 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,const unsigned int,const GLbyte*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const GLshort*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const GLint*) {}
|
|
|
|
virtual void apply(AttributeType,const unsigned int,const GLubyte*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const GLushort*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const GLuint*) {}
|
|
|
|
virtual void apply(AttributeType,const unsigned int,const float*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const Vec2*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const Vec3*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const Vec4*) {}
|
|
virtual void apply(AttributeType,const unsigned int,const UByte4*) {}
|
|
};
|
|
|
|
/** return true if the Drawable subclass supports accept(ConstAttributeFunctor&).*/
|
|
virtual bool supports(ConstAttributeFunctor&) const { return false; }
|
|
|
|
/** accept an AttributeFunctor and call its methods to tell it about the interal 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 {}
|
|
|
|
|
|
class PrimitiveFunctor
|
|
{
|
|
public:
|
|
|
|
virtual ~PrimitiveFunctor() {}
|
|
|
|
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
|
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
|
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
|
|
|
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
|
|
|
virtual void begin(GLenum mode) = 0;
|
|
virtual void vertex(const Vec2& vert) = 0;
|
|
virtual void vertex(const Vec3& vert) = 0;
|
|
virtual void vertex(const Vec4& vert) = 0;
|
|
virtual void vertex(float x,float y) = 0;
|
|
virtual void vertex(float x,float y,float z) = 0;
|
|
virtual void vertex(float x,float y,float z,float w) = 0;
|
|
virtual void end() = 0;
|
|
|
|
};
|
|
|
|
class PrimitiveIndexFunctor
|
|
{
|
|
public:
|
|
|
|
virtual ~PrimitiveIndexFunctor() {}
|
|
|
|
virtual void setVertexArray(unsigned int count,const Vec2* vertices) = 0;
|
|
virtual void setVertexArray(unsigned int count,const Vec3* vertices) = 0;
|
|
virtual void setVertexArray(unsigned int count,const Vec4* vertices) = 0;
|
|
|
|
virtual void drawArrays(GLenum mode,GLint first,GLsizei count) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLubyte* indices) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLushort* indices) = 0;
|
|
virtual void drawElements(GLenum mode,GLsizei count,const GLuint* indices) = 0;
|
|
|
|
virtual void begin(GLenum mode) = 0;
|
|
virtual void vertex(unsigned int pos) = 0;
|
|
virtual void end() = 0;
|
|
|
|
};
|
|
|
|
/** return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/
|
|
virtual bool supports(PrimitiveFunctor&) const { return false; }
|
|
|
|
/** accept a PrimtiveFunctor and call its methods to tell it about the interal primtives that this Drawable has.
|
|
* return true if functor handled by drawable, return false on failure of drawable to generate functor calls.
|
|
* Note, PrimtiveFunctor only provide const access of the primtives, 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(PrimitiveIndexFunctor&) const { return false; }
|
|
|
|
/** accept a PrimtiveIndexFunctor and call its methods to tell it about the interal primtives that this Drawable has.
|
|
* return true if functor handled by drawable, return false on failure of drawable to generate functor calls.
|
|
* Note, PrimtiveIndexFunctor only provide const access of the primtives, as primitives may be procedurally generated
|
|
* so one cannot modify it.*/
|
|
virtual void accept(PrimitiveIndexFunctor&) const {}
|
|
|
|
|
|
/** Extensions class which encapsulates the querring of extensions and
|
|
* associated function pointers, and provide convinience wrappers to
|
|
* check for the extensions or use the associated functions.*/
|
|
class SG_EXPORT Extensions : public osg::Referenced
|
|
{
|
|
public:
|
|
Extensions();
|
|
|
|
Extensions(const Extensions& rhs);
|
|
|
|
void lowestCommonDenominator(const Extensions& rhs);
|
|
|
|
void setupGLExtenions();
|
|
|
|
void setVertexProgramSupported(bool flag) { _isVertexProgramSupported=flag; }
|
|
bool isVertexProgramSupported() const { return _isVertexProgramSupported; }
|
|
|
|
void setSecondaryColorSupported(bool flag) { _isSecondaryColorSupported=flag; }
|
|
bool isSecondaryColorSupported() const { return _isSecondaryColorSupported; }
|
|
|
|
void setFogCoordSupported(bool flag) { _isFogCoordSupported=flag; }
|
|
bool isFogCoordSupported() const { return _isFogCoordSupported; }
|
|
|
|
void setMultiTexSupported(bool flag) { _isMultiTexSupported=flag; }
|
|
bool isMultiTexSupported() const { return _isMultiTexSupported; }
|
|
|
|
void setOcclusionQuerySupported(bool flag) { _isOcclusionQuerySupported=flag; }
|
|
bool isOcclusionQuerySupported() const { return _isOcclusionQuerySupported; }
|
|
|
|
void setARBOcclusionQuerySupported(bool flag) { _isARBOcclusionQuerySupported=flag; }
|
|
bool isARBOcclusionQuerySupported() const { return _isARBOcclusionQuerySupported; }
|
|
|
|
void glSecondaryColor3ubv(const GLubyte* coord) const;
|
|
void glSecondaryColor3fv(const GLfloat* coord) const;
|
|
|
|
void glFogCoordfv(const GLfloat* coord) const;
|
|
|
|
void glMultiTexCoord1f(GLenum target,GLfloat coord) const;
|
|
void glMultiTexCoord2fv(GLenum target,const GLfloat* coord) const;
|
|
void glMultiTexCoord3fv(GLenum target,const GLfloat* coord) const;
|
|
void glMultiTexCoord4fv(GLenum target,const GLfloat* coord) const;
|
|
|
|
void glVertexAttrib1s(unsigned int index, GLshort s) const;
|
|
void glVertexAttrib1f(unsigned int index, GLfloat f) const;
|
|
void glVertexAttrib2fv(unsigned int index, const GLfloat * v) const;
|
|
void glVertexAttrib3fv(unsigned int index, const GLfloat * v) const;
|
|
void glVertexAttrib4fv(unsigned int index, const GLfloat * v) const;
|
|
void glVertexAttrib4ubv(unsigned int index, const GLubyte * v) const;
|
|
void glVertexAttrib4Nubv(unsigned int index, const GLubyte * v) const;
|
|
|
|
void glGenBuffers (GLsizei n, GLuint *buffers) const;
|
|
void glBindBuffer (GLenum target, GLuint buffer) const;
|
|
void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const;
|
|
void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const;
|
|
void glDeleteBuffers (GLsizei n, const GLuint *buffers) const;
|
|
|
|
void glGenOcclusionQueries( GLsizei n, GLuint *ids ) const;
|
|
void glDeleteOcclusionQueries( GLsizei n, const GLuint *ids ) const;
|
|
GLboolean glIsOcclusionQuery( GLuint id ) const;
|
|
void glBeginOcclusionQuery( GLuint id ) const;
|
|
void glEndOcclusionQuery() const;
|
|
void glGetOcclusionQueryiv( GLuint id, GLenum pname, GLint *params ) const;
|
|
void glGetOcclusionQueryuiv( GLuint id, GLenum pname, GLuint *params ) const;
|
|
|
|
void glGetQueryiv(GLenum target, GLenum pname, GLint *params) const;
|
|
void glGenQueries(GLsizei n, GLuint *ids) const;
|
|
void glBeginQuery(GLenum target, GLuint id) const;
|
|
void glEndQuery(GLenum target) const;
|
|
GLboolean glIsQuery(GLuint id) const;
|
|
void glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) const;
|
|
void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const;
|
|
|
|
protected:
|
|
|
|
typedef void (APIENTRY * FogCoordProc) (const GLfloat* coord);
|
|
|
|
typedef void (APIENTRY * VertexAttrib1sProc) (unsigned int index, GLshort s);
|
|
typedef void (APIENTRY * VertexAttrib1fProc) (unsigned int index, GLfloat f);
|
|
typedef void (APIENTRY * VertexAttribfvProc) (unsigned int index, const GLfloat * v);
|
|
typedef void (APIENTRY * VertexAttribubvProc) (unsigned int index, const GLubyte * v);
|
|
|
|
typedef void (APIENTRY * SecondaryColor3ubvProc) (const GLubyte* coord);
|
|
typedef void (APIENTRY * SecondaryColor3fvProc) (const GLfloat* coord);
|
|
|
|
typedef void (APIENTRY * MultiTexCoord1fProc) (GLenum target,GLfloat coord);
|
|
typedef void (APIENTRY * MultiTexCoordfvProc) (GLenum target,const GLfloat* coord);
|
|
|
|
typedef void (APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers);
|
|
typedef void (APIENTRY * BindBufferProc) (GLenum target, GLuint buffer);
|
|
typedef void (APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage);
|
|
typedef void (APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data);
|
|
typedef void (APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers);
|
|
|
|
typedef void (APIENTRY * GenOcclusionQueriesProc) ( GLsizei n, GLuint *ids );
|
|
typedef void (APIENTRY * DeleteOcclusionQueriesProc) ( GLsizei n, const GLuint *ids );
|
|
typedef GLboolean (APIENTRY * IsOcclusionQueryProc) ( GLuint id );
|
|
typedef void (APIENTRY * BeginOcclusionQueryProc) ( GLuint id );
|
|
typedef void (APIENTRY * EndOcclusionQueryProc) ();
|
|
typedef void (APIENTRY * GetOcclusionQueryivProc) ( GLuint id, GLenum pname, GLint *params );
|
|
typedef void (APIENTRY * GetOcclusionQueryuivProc) ( GLuint id, GLenum pname, GLuint *params );
|
|
|
|
typedef void (APIENTRY *GenQueriesProc) (GLsizei n, GLuint *ids);
|
|
typedef void (APIENTRY *DeleteQueriesProc) (GLsizei n, const GLuint *ids);
|
|
typedef GLboolean (APIENTRY *IsQueryProc) (GLuint id);
|
|
typedef void (APIENTRY *BeginQueryProc) (GLenum target, GLuint id);
|
|
typedef void (APIENTRY *EndQueryProc) (GLenum target);
|
|
typedef void (APIENTRY *GetQueryivProc) (GLenum target, GLenum pname, GLint *params);
|
|
typedef void (APIENTRY *GetQueryObjectivProc) (GLuint id, GLenum pname, GLint *params);
|
|
typedef void (APIENTRY *GetQueryObjectuivProc) (GLuint id, GLenum pname, GLuint *params);
|
|
|
|
~Extensions() {}
|
|
|
|
bool _isVertexProgramSupported;
|
|
bool _isSecondaryColorSupported;
|
|
bool _isFogCoordSupported;
|
|
bool _isMultiTexSupported;
|
|
bool _isOcclusionQuerySupported;
|
|
bool _isARBOcclusionQuerySupported;
|
|
|
|
FogCoordProc _glFogCoordfv;
|
|
|
|
SecondaryColor3ubvProc _glSecondaryColor3ubv;
|
|
SecondaryColor3fvProc _glSecondaryColor3fv;
|
|
|
|
VertexAttrib1sProc _glVertexAttrib1s;
|
|
VertexAttrib1fProc _glVertexAttrib1f;
|
|
VertexAttribfvProc _glVertexAttrib2fv;
|
|
VertexAttribfvProc _glVertexAttrib3fv;
|
|
VertexAttribfvProc _glVertexAttrib4fv;
|
|
VertexAttribubvProc _glVertexAttrib4ubv;
|
|
VertexAttribubvProc _glVertexAttrib4Nubv;
|
|
|
|
MultiTexCoord1fProc _glMultiTexCoord1f;
|
|
MultiTexCoordfvProc _glMultiTexCoord2fv;
|
|
MultiTexCoordfvProc _glMultiTexCoord3fv;
|
|
MultiTexCoordfvProc _glMultiTexCoord4fv;
|
|
|
|
GenBuffersProc _glGenBuffers;
|
|
BindBufferProc _glBindBuffer;
|
|
BufferDataProc _glBufferData;
|
|
BufferSubDataProc _glBufferSubData;
|
|
DeleteBuffersProc _glDeleteBuffers;
|
|
|
|
GenOcclusionQueriesProc _glGenOcclusionQueries;
|
|
DeleteOcclusionQueriesProc _glDeleteOcclusionQueries;
|
|
IsOcclusionQueryProc _glIsOcclusionQuery;
|
|
BeginOcclusionQueryProc _glBeginOcclusionQuery;
|
|
EndOcclusionQueryProc _glEndOcclusionQuery;
|
|
GetOcclusionQueryivProc _glGetOcclusionQueryiv;
|
|
GetOcclusionQueryuivProc _glGetOcclusionQueryuiv;
|
|
|
|
GenQueriesProc _gl_gen_queries_arb;
|
|
DeleteQueriesProc _gl_delete_queries_arb;
|
|
IsQueryProc _gl_is_query_arb;
|
|
BeginQueryProc _gl_begin_query_arb;
|
|
EndQueryProc _gl_end_query_arb;
|
|
GetQueryivProc _gl_get_queryiv_arb;
|
|
GetQueryObjectivProc _gl_get_query_objectiv_arb;
|
|
GetQueryObjectuivProc _gl_get_query_objectuiv_arb;
|
|
|
|
};
|
|
|
|
/** Function to call to get the extension of a specified context.
|
|
* If the Exentsion object for that context has not yet been created then
|
|
* and the 'createIfNotInitalized' flag been set to false then returns NULL.
|
|
* If 'createIfNotInitalized' is true then the Extensions object is
|
|
* automatically created. However, in this case the extension object
|
|
* only be created with the graphics context associated with ContextID..*/
|
|
static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized);
|
|
|
|
/** setExtensions allows users to override the extensions across graphics contexts.
|
|
* typically used when you have different extensions supported across graphics pipes
|
|
* but need to ensure that they all use the same low common denominator extensions.*/
|
|
static void setExtensions(unsigned int contextID,Extensions* extensions);
|
|
|
|
|
|
protected:
|
|
|
|
Drawable& operator = (const Drawable&) { return *this;}
|
|
|
|
virtual ~Drawable();
|
|
|
|
/** compute the bounding box of the drawable. Method must be
|
|
implemented by subclasses.*/
|
|
virtual bool computeBound() const;
|
|
|
|
/** set the bounding box .*/
|
|
void setBound(const BoundingBox& bb) const;
|
|
|
|
void addParent(osg::Node* node);
|
|
void removeParent(osg::Node* node);
|
|
|
|
ParentList _parents;
|
|
friend class Node;
|
|
friend class Geode;
|
|
|
|
ref_ptr<StateSet> _stateset;
|
|
|
|
mutable BoundingBox _bbox;
|
|
mutable bool _bbox_computed;
|
|
|
|
ref_ptr<Shape> _shape;
|
|
|
|
bool _supportsDisplayList;
|
|
bool _useDisplayList;
|
|
bool _supportsVertexBufferObjects;
|
|
bool _useVertexBufferObjects;
|
|
|
|
typedef osg::buffered_value<GLuint> GLObjectList;
|
|
mutable GLObjectList _globjList;
|
|
mutable GLObjectList _vboList;
|
|
|
|
ref_ptr<UpdateCallback> _updateCallback;
|
|
ref_ptr<CullCallback> _cullCallback;
|
|
ref_ptr<DrawCallback> _drawCallback;
|
|
|
|
|
|
};
|
|
|
|
inline void Drawable::draw(State& state) const
|
|
{
|
|
if (_useDisplayList && !(_supportsVertexBufferObjects && _useVertexBufferObjects && state.isVertexBufferObjectSupported()))
|
|
{
|
|
// get the contextID (user defined ID of 0 upwards) for the
|
|
// current OpenGL context.
|
|
unsigned int contextID = state.getContextID();
|
|
|
|
// get the globj for the current contextID.
|
|
GLuint& globj = _globjList[contextID];
|
|
|
|
// call the globj if already set otherwise compile and execute.
|
|
if( globj != 0 )
|
|
{
|
|
glCallList( globj );
|
|
}
|
|
else if (_useDisplayList)
|
|
{
|
|
#ifdef USE_SEPARATE_COMPILE_AND_EXECUTE
|
|
globj = glGenLists( 1 );
|
|
glNewList( globj, GL_COMPILE );
|
|
if (_drawCallback.valid())
|
|
_drawCallback->drawImplementation(state,this);
|
|
else
|
|
drawImplementation(state);
|
|
glEndList();
|
|
|
|
glCallList( globj);
|
|
#else
|
|
globj = glGenLists( 1 );
|
|
glNewList( globj, GL_COMPILE_AND_EXECUTE );
|
|
if (_drawCallback.valid())
|
|
_drawCallback->drawImplementation(state,this);
|
|
else
|
|
drawImplementation(state);
|
|
glEndList();
|
|
#endif
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// draw object as nature intended..
|
|
if (_drawCallback.valid())
|
|
_drawCallback->drawImplementation(state,this);
|
|
else
|
|
drawImplementation(state);
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif
|