| 1 | /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield |
|---|
| 2 | * |
|---|
| 3 | * This library is open source and may be redistributed and/or modified under |
|---|
| 4 | * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or |
|---|
| 5 | * (at your option) any later version. The full license is in LICENSE file |
|---|
| 6 | * included with this distribution, and on the openscenegraph.org website. |
|---|
| 7 | * |
|---|
| 8 | * This library is distributed in the hope that it will be useful, |
|---|
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 11 | * OpenSceneGraph Public License for more details. |
|---|
| 12 | */ |
|---|
| 13 | |
|---|
| 14 | #ifndef OSG_DRAWABLE |
|---|
| 15 | #define OSG_DRAWABLE 1 |
|---|
| 16 | |
|---|
| 17 | #include <osg/BoundingBox> |
|---|
| 18 | #include <osg/Shape> |
|---|
| 19 | #include <osg/BufferObject> |
|---|
| 20 | #include <osg/PrimitiveSet> |
|---|
| 21 | #include <osg/RenderInfo> |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | #ifndef GL_NV_occlusion_query |
|---|
| 25 | |
|---|
| 26 | #define GL_OCCLUSION_TEST_HP 0x8165 |
|---|
| 27 | #define GL_OCCLUSION_TEST_RESULT_HP 0x8166 |
|---|
| 28 | #define GL_PIXEL_COUNTER_BITS_NV 0x8864 |
|---|
| 29 | #define GL_CURRENT_OCCLUSION_QUERY_ID_NV 0x8865 |
|---|
| 30 | #define GL_PIXEL_COUNT_NV 0x8866 |
|---|
| 31 | #define GL_PIXEL_COUNT_AVAILABLE_NV 0x8867 |
|---|
| 32 | |
|---|
| 33 | #endif |
|---|
| 34 | |
|---|
| 35 | #ifndef GL_ARB_occlusion_query |
|---|
| 36 | |
|---|
| 37 | #define GL_SAMPLES_PASSED_ARB 0x8914 |
|---|
| 38 | #define GL_QUERY_COUNTER_BITS_ARB 0x8864 |
|---|
| 39 | #define GL_CURRENT_QUERY_ARB 0x8865 |
|---|
| 40 | #define GL_QUERY_RESULT_ARB 0x8866 |
|---|
| 41 | #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 |
|---|
| 42 | |
|---|
| 43 | #endif |
|---|
| 44 | |
|---|
| 45 | |
|---|
| 46 | #ifndef GL_TIME_ELAPSED |
|---|
| 47 | #define GL_TIME_ELAPSED 0x88BF |
|---|
| 48 | #define GL_TIMESTAMP 0x8E28 |
|---|
| 49 | #endif |
|---|
| 50 | |
|---|
| 51 | #ifndef GL_QUERY_RESULT |
|---|
| 52 | #define GL_QUERY_RESULT 0x8866 |
|---|
| 53 | #define GL_QUERY_RESULT_AVAILABLE 0x8867 |
|---|
| 54 | #endif |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | #if !defined(GL_EXT_timer_query) && !defined(OSG_GL3_AVAILABLE) |
|---|
| 58 | #ifdef _WIN32 |
|---|
| 59 | typedef __int64 GLint64EXT; |
|---|
| 60 | typedef unsigned __int64 GLuint64EXT; |
|---|
| 61 | #else |
|---|
| 62 | typedef long long int GLint64EXT; |
|---|
| 63 | typedef unsigned long long int GLuint64EXT; |
|---|
| 64 | #endif |
|---|
| 65 | #endif |
|---|
| 66 | |
|---|
| 67 | |
|---|
| 68 | namespace osg { |
|---|
| 69 | |
|---|
| 70 | |
|---|
| 71 | class Vec2f; |
|---|
| 72 | class Vec3f; |
|---|
| 73 | class Vec4f; |
|---|
| 74 | class Vec4ub; |
|---|
| 75 | class Geometry; |
|---|
| 76 | class NodeVisitor; |
|---|
| 77 | class ArrayDispatchers; |
|---|
| 78 | |
|---|
| 79 | // this is defined to alter the way display lists are compiled inside the |
|---|
| 80 | // the draw method, it has been found that the NVidia drivers fail completely |
|---|
| 81 | // to optimize COMPILE_AND_EXECUTE in fact make it go slower than for no display |
|---|
| 82 | // lists, but optimize a separate COMPILE very well?! Define it as default |
|---|
| 83 | // the use of a separate COMPILE, then glCallList rather than use COMPILE_AND_EXECUTE. |
|---|
| 84 | |
|---|
| 85 | #define USE_SEPARATE_COMPILE_AND_EXECUTE |
|---|
| 86 | |
|---|
| 87 | /** Pure virtual base class for drawable geometry. In OSG, everything that can |
|---|
| 88 | * be rendered is implemented as a class derived from \c Drawable. The |
|---|
| 89 | * \c Drawable class contains no drawing primitives, since these are provided |
|---|
| 90 | * by subclasses such as \c osg::Geometry. |
|---|
| 91 | * <p>Notice that a \c Drawable is not a \c Node, and therefore it cannot be |
|---|
| 92 | * directly added to a scene graph. Instead, <tt>Drawable</tt>s are attached to |
|---|
| 93 | * <tt>Geode</tt>s, which are scene graph nodes. |
|---|
| 94 | * <p>The OpenGL state that must be used when rendering a \c Drawable is |
|---|
| 95 | * represented by a \c StateSet. Since a \c Drawable has a reference |
|---|
| 96 | * (\c osg::ref_ptr) to a \c StateSet, <tt>StateSet</tt>s can be shared between |
|---|
| 97 | * different <tt>Drawable</tt>s. In fact, sharing <tt>StateSet</tt>s is a good |
|---|
| 98 | * way to improve performance, since this allows OSG to reduce the number of |
|---|
| 99 | * expensive changes in the OpenGL state. |
|---|
| 100 | * <p>Finally, <tt>Drawable</tt>s can also be shared between different |
|---|
| 101 | * <tt>Geode</tt>s, so that the same geometry (loaded to memory just once) can |
|---|
| 102 | * be used in different parts of the scene graph. |
|---|
| 103 | */ |
|---|
| 104 | class OSG_EXPORT Drawable : public Object |
|---|
| 105 | { |
|---|
| 106 | public: |
|---|
| 107 | |
|---|
| 108 | static unsigned int s_numberDrawablesReusedLastInLastFrame; |
|---|
| 109 | static unsigned int s_numberNewDrawablesInLastFrame; |
|---|
| 110 | static unsigned int s_numberDeletedDrawablesInLastFrame; |
|---|
| 111 | |
|---|
| 112 | Drawable(); |
|---|
| 113 | |
|---|
| 114 | /** Copy constructor using CopyOp to manage deep vs shallow copy.*/ |
|---|
| 115 | Drawable(const Drawable& drawable,const CopyOp& copyop=CopyOp::SHALLOW_COPY); |
|---|
| 116 | |
|---|
| 117 | virtual bool isSameKindAs(const Object* obj) const { return dynamic_cast<const Drawable*>(obj)!=NULL; } |
|---|
| 118 | virtual const char* libraryName() const { return "osg"; } |
|---|
| 119 | virtual const char* className() const { return "Drawable"; } |
|---|
| 120 | |
|---|
| 121 | /** Convert 'this' into a Geometry pointer if Drawable is a Geometry, otherwise return 0. |
|---|
| 122 | * Equivalent to dynamic_cast<Geometry*>(this).*/ |
|---|
| 123 | virtual Geometry* asGeometry() { return 0; } |
|---|
| 124 | |
|---|
| 125 | /** Convert 'const this' into a const Geometry pointer if Drawable is a Geometry, otherwise return 0. |
|---|
| 126 | * Equivalent to dynamic_cast<const Geometry*>(this).*/ |
|---|
| 127 | virtual const Geometry* asGeometry() const { return 0; } |
|---|
| 128 | |
|---|
| 129 | |
|---|
| 130 | /** Compute the DataVariance based on an assessment of callback etc.*/ |
|---|
| 131 | virtual void computeDataVariance(); |
|---|
| 132 | |
|---|
| 133 | |
|---|
| 134 | /** A vector of osg::Node pointers which is used to store the parent(s) of drawable.*/ |
|---|
| 135 | typedef std::vector<Node*> ParentList; |
|---|
| 136 | |
|---|
| 137 | /** Get the parent list of drawable. */ |
|---|
| 138 | inline const ParentList& getParents() const { return _parents; } |
|---|
| 139 | |
|---|
| 140 | /** Get the a copy of parent list of node. A copy is returned to |
|---|
| 141 | * prevent modification of the parent list.*/ |
|---|
| 142 | inline ParentList getParents() { return _parents; } |
|---|
| 143 | |
|---|
| 144 | /** Get a single parent of Drawable. |
|---|
| 145 | * @param i index of the parent to get. |
|---|
| 146 | * @return the parent i. |
|---|
| 147 | */ |
|---|
| 148 | inline Node* getParent(unsigned int i) { return _parents[i]; } |
|---|
| 149 | /** Get a single const parent of Drawable. |
|---|
| 150 | * @param i index of the parent to get. |
|---|
| 151 | * @return the parent i. |
|---|
| 152 | */ |
|---|
| 153 | inline const Node* getParent(unsigned int i) const { return _parents[i]; } |
|---|
| 154 | |
|---|
| 155 | /** |
|---|
| 156 | * Get the number of parents of node. |
|---|
| 157 | * @return the number of parents of this node. |
|---|
| 158 | */ |
|---|
| 159 | inline unsigned int getNumParents() const { return static_cast<unsigned int>(_parents.size()); } |
|---|
| 160 | |
|---|
| 161 | /** Get the list of matrices that transform this node from local coordinates to world coordinates. |
|---|
| 162 | * The optional Node* haltTraversalAtNode allows the user to prevent traversal beyond a specifed node. */ |
|---|
| 163 | MatrixList getWorldMatrices(const osg::Node* haltTraversalAtNode=0) const; |
|---|
| 164 | |
|---|
| 165 | |
|---|
| 166 | /** Set the StateSet attached to the Drawable. |
|---|
| 167 | Previously attached StateSet are automatically unreferenced on |
|---|
| 168 | assignment of a new drawstate.*/ |
|---|
| 169 | void setStateSet(StateSet* stateset); |
|---|
| 170 | |
|---|
| 171 | /** Get the attached StateSet.*/ |
|---|
| 172 | inline StateSet* getStateSet() { return _stateset.get();} |
|---|
| 173 | |
|---|
| 174 | /** Get the attached const StateSet.*/ |
|---|
| 175 | inline const StateSet* getStateSet() const { return _stateset.get();} |
|---|
| 176 | |
|---|
| 177 | /** Get the attached const StateSet, |
|---|
| 178 | * if one is not already attached create one, |
|---|
| 179 | * attach it to the drawable and return a pointer to it.*/ |
|---|
| 180 | StateSet* getOrCreateStateSet(); |
|---|
| 181 | |
|---|
| 182 | |
|---|
| 183 | /** Set the initial bounding volume to use when computing the overall bounding volume.*/ |
|---|
| 184 | void setInitialBound(const osg::BoundingBox& bbox) { _initialBound = bbox; dirtyBound(); } |
|---|
| 185 | |
|---|
| 186 | /** Set the initial bounding volume to use when computing the overall bounding volume.*/ |
|---|
| 187 | const BoundingBox& getInitialBound() const { return _initialBound; } |
|---|
| 188 | |
|---|
| 189 | /** Dirty the bounding box, forcing a computeBound() on the next call |
|---|
| 190 | * to getBound(). Should be called in the internal geometry of the Drawable |
|---|
| 191 | * is modified.*/ |
|---|
| 192 | void dirtyBound(); |
|---|
| 193 | |
|---|
| 194 | /** Get BoundingBox of Drawable. |
|---|
| 195 | * If the BoundingBox is not up to date then its updated via an internal call to computeBond(). |
|---|
| 196 | */ |
|---|
| 197 | inline const BoundingBox& getBound() const |
|---|
| 198 | { |
|---|
| 199 | if(!_boundingBoxComputed) |
|---|
| 200 | { |
|---|
| 201 | _boundingBox = _initialBound; |
|---|
| 202 | if (_computeBoundCallback.valid()) |
|---|
| 203 | _boundingBox.expandBy(_computeBoundCallback->computeBound(*this)); |
|---|
| 204 | else |
|---|
| 205 | _boundingBox.expandBy(computeBound()); |
|---|
| 206 | |
|---|
| 207 | _boundingBoxComputed = true; |
|---|
| 208 | } |
|---|
| 209 | return _boundingBox; |
|---|
| 210 | } |
|---|
| 211 | |
|---|
| 212 | |
|---|
| 213 | /** Compute the bounding box around Drawables's geometry.*/ |
|---|
| 214 | virtual BoundingBox computeBound() const; |
|---|
| 215 | |
|---|
| 216 | /** Callback to allow users to override the default computation of bounding volume. */ |
|---|
| 217 | struct ComputeBoundingBoxCallback : public osg::Object |
|---|
| 218 | { |
|---|
| 219 | ComputeBoundingBoxCallback() {} |
|---|
| 220 | |
|---|
| 221 | ComputeBoundingBoxCallback(const ComputeBoundingBoxCallback&,const CopyOp&) {} |
|---|
| 222 | |
|---|
| 223 | META_Object(osg,ComputeBoundingBoxCallback); |
|---|
| 224 | |
|---|
| 225 | virtual BoundingBox computeBound(const osg::Drawable&) const { return BoundingBox(); } |
|---|
| 226 | }; |
|---|
| 227 | |
|---|
| 228 | /** Set the compute bound callback to override the default computeBound.*/ |
|---|
| 229 | void setComputeBoundingBoxCallback(ComputeBoundingBoxCallback* callback) { _computeBoundCallback = callback; } |
|---|
| 230 | |
|---|
| 231 | /** Get the compute bound callback.*/ |
|---|
| 232 | ComputeBoundingBoxCallback* getComputeBoundingBoxCallback() { return _computeBoundCallback.get(); } |
|---|
| 233 | |
|---|
| 234 | /** Get the const compute bound callback.*/ |
|---|
| 235 | const ComputeBoundingBoxCallback* getComputeBoundingBoxCallback() const { return _computeBoundCallback.get(); } |
|---|
| 236 | |
|---|
| 237 | |
|---|
| 238 | /** Set the Shape of the \c Drawable. The shape can be used to |
|---|
| 239 | * speed up collision detection or as a guide for procedural |
|---|
| 240 | * geometry generation. |
|---|
| 241 | * @see osg::Shape. |
|---|
| 242 | */ |
|---|
| 243 | inline void setShape(Shape* shape) { _shape = shape; } |
|---|
| 244 | |
|---|
| 245 | /** Get the Shape of the Drawable.*/ |
|---|
| 246 | inline Shape* getShape() { return _shape.get(); } |
|---|
| 247 | |
|---|
| 248 | /** Get the const Shape of the const Drawable.*/ |
|---|
| 249 | inline const Shape* getShape() const { return _shape.get(); } |
|---|
| 250 | |
|---|
| 251 | |
|---|
| 252 | |
|---|
| 253 | /** Set the drawable so that it can or cannot be used in conjunction with OpenGL |
|---|
| 254 | * display lists. When set to true, calls to Drawable::setUseDisplayList, |
|---|
| 255 | * whereas when set to false, no display lists can be created and calls |
|---|
| 256 | * to setUseDisplayList are ignored, and a warning is produced. The latter |
|---|
| 257 | * is typically used to guard against the switching on of display lists |
|---|
| 258 | * on objects with dynamic internal data such as continuous Level of Detail |
|---|
| 259 | * algorithms.*/ |
|---|
| 260 | void setSupportsDisplayList(bool flag); |
|---|
| 261 | |
|---|
| 262 | /** Get whether display lists are supported for this drawable instance.*/ |
|---|
| 263 | inline bool getSupportsDisplayList() const { return _supportsDisplayList; } |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | /** When set to true, force the draw method to use OpenGL Display List for rendering. |
|---|
| 267 | If false, rendering directly. If the display list has not been compiled |
|---|
| 268 | already, the next call to draw will automatically create the display list.*/ |
|---|
| 269 | void setUseDisplayList(bool flag); |
|---|
| 270 | |
|---|
| 271 | /** Return whether OpenGL display lists are being used for rendering.*/ |
|---|
| 272 | inline bool getUseDisplayList() const { return _useDisplayList; } |
|---|
| 273 | |
|---|
| 274 | /** Return OpenGL display list for specified contextID. */ |
|---|
| 275 | inline GLuint& getDisplayList(unsigned int contextID) const { return _globjList[contextID]; } |
|---|
| 276 | |
|---|
| 277 | /** When set to true, ignore the setUseDisplayList() settings, and hints to the drawImplementation |
|---|
| 278 | method to use OpenGL vertex buffer objects for rendering.*/ |
|---|
| 279 | virtual void setUseVertexBufferObjects(bool flag); |
|---|
| 280 | |
|---|
| 281 | /** Return whether OpenGL vertex buffer objects should be used when supported by OpenGL driver.*/ |
|---|
| 282 | inline bool getUseVertexBufferObjects() const { return _useVertexBufferObjects; } |
|---|
| 283 | |
|---|
| 284 | |
|---|
| 285 | /** Force a recompile on next draw() of any OpenGL display list associated with this geoset.*/ |
|---|
| 286 | virtual void dirtyDisplayList(); |
|---|
| 287 | |
|---|
| 288 | |
|---|
| 289 | /** Return the estimated size of GLObjects (display lists/vertex buffer objects) that are associated with this drawable. |
|---|
| 290 | * This size is used a hint for reuse of deleted display lists/vertex buffer objects. */ |
|---|
| 291 | virtual unsigned int getGLObjectSizeHint() const { return 0; } |
|---|
| 292 | |
|---|
| 293 | |
|---|
| 294 | |
|---|
| 295 | /** Draw OpenGL primitives. |
|---|
| 296 | * If the \c Drawable has \c _useDisplayList set to \c true, then use |
|---|
| 297 | * an OpenGL display list, automatically compiling one if required. |
|---|
| 298 | * Otherwise, call \c drawImplementation(). |
|---|
| 299 | * @note This method should \e not be overridden in subclasses, as it |
|---|
| 300 | * manages the optional display list (notice this is not even |
|---|
| 301 | * \c virtual). Subclasses should override |
|---|
| 302 | * \c drawImplementation() instead. |
|---|
| 303 | */ |
|---|
| 304 | inline void draw(RenderInfo& renderInfo) const; |
|---|
| 305 | |
|---|
| 306 | /** Immediately compile this \c Drawable into an OpenGL Display List/VertexBufferObjects. |
|---|
| 307 | * @note Operation is ignored if \c _useDisplayList is \c false or VertexBufferObjects are not used. |
|---|
| 308 | */ |
|---|
| 309 | virtual void compileGLObjects(RenderInfo& renderInfo) const; |
|---|
| 310 | |
|---|
| 311 | /** Set whether to use a mutex to ensure ref() and unref() are thread safe.*/ |
|---|
| 312 | virtual void setThreadSafeRefUnref(bool threadSafe); |
|---|
| 313 | |
|---|
| 314 | /** Resize any per context GLObject buffers to specified size. */ |
|---|
| 315 | virtual void resizeGLObjectBuffers(unsigned int maxSize); |
|---|
| 316 | |
|---|
| 317 | /** If State is non-zero, this function releases OpenGL objects for |
|---|
| 318 | * the specified graphics context. Otherwise, releases OpenGL objects |
|---|
| 319 | * for all graphics contexts. */ |
|---|
| 320 | virtual void releaseGLObjects(State* state=0) const; |
|---|
| 321 | |
|---|
| 322 | struct UpdateCallback : public virtual osg::Object |
|---|
| 323 | { |
|---|
| 324 | UpdateCallback() {} |
|---|
| 325 | |
|---|
| 326 | UpdateCallback(const UpdateCallback&,const CopyOp&) {} |
|---|
| 327 | |
|---|
| 328 | META_Object(osg,UpdateCallback); |
|---|
| 329 | |
|---|
| 330 | /** do customized update code.*/ |
|---|
| 331 | virtual void update(osg::NodeVisitor*, osg::Drawable*) {} |
|---|
| 332 | }; |
|---|
| 333 | |
|---|
| 334 | /** Set the UpdateCallback which allows users to attach customize the updating of an object during the update traversal. */ |
|---|
| 335 | virtual void setUpdateCallback(UpdateCallback* ac); |
|---|
| 336 | |
|---|
| 337 | /** Get the non const UpdateCallback.*/ |
|---|
| 338 | UpdateCallback* getUpdateCallback() { return _updateCallback.get(); } |
|---|
| 339 | |
|---|
| 340 | /** Get the const UpdateCallback.*/ |
|---|
| 341 | const UpdateCallback* getUpdateCallback() const { return _updateCallback.get(); } |
|---|
| 342 | |
|---|
| 343 | /** Return whether this Drawable has update callbacks associated with it, and therefore must be traversed.*/ |
|---|
| 344 | bool requiresUpdateTraversal() const { return _updateCallback.valid() || (_stateset.valid() && _stateset->requiresUpdateTraversal()); } |
|---|
| 345 | |
|---|
| 346 | |
|---|
| 347 | struct EventCallback : public virtual osg::Object |
|---|
| 348 | { |
|---|
| 349 | EventCallback() {} |
|---|
| 350 | |
|---|
| 351 | EventCallback(const EventCallback&,const CopyOp&) {} |
|---|
| 352 | |
|---|
| 353 | META_Object(osg,EventCallback); |
|---|
| 354 | |
|---|
| 355 | /** do customized Event code. */ |
|---|
| 356 | virtual void event(osg::NodeVisitor*, osg::Drawable*) {} |
|---|
| 357 | }; |
|---|
| 358 | |
|---|
| 359 | /** Set the EventCallback which allows users to attach customize the updating of an object during the Event traversal.*/ |
|---|
| 360 | virtual void setEventCallback(EventCallback* ac); |
|---|
| 361 | |
|---|
| 362 | /** Get the non const EventCallback.*/ |
|---|
| 363 | EventCallback* getEventCallback() { return _eventCallback.get(); } |
|---|
| 364 | |
|---|
| 365 | /** Get the const EventCallback.*/ |
|---|
| 366 | const EventCallback* getEventCallback() const { return _eventCallback.get(); } |
|---|
| 367 | |
|---|
| 368 | /** Return whether this Drawable has event callbacks associated with it, and therefore must be traversed.*/ |
|---|
| 369 | bool requiresEventTraversal() const { return _eventCallback.valid() || (_stateset.valid() && _stateset->requiresEventTraversal()); } |
|---|
| 370 | |
|---|
| 371 | |
|---|
| 372 | struct CullCallback : public virtual osg::Object |
|---|
| 373 | { |
|---|
| 374 | CullCallback() {} |
|---|
| 375 | |
|---|
| 376 | CullCallback(const CullCallback&,const CopyOp&) {} |
|---|
| 377 | |
|---|
| 378 | META_Object(osg,CullCallback); |
|---|
| 379 | |
|---|
| 380 | /** deprecated.*/ |
|---|
| 381 | virtual bool cull(osg::NodeVisitor*, osg::Drawable*, osg::State*) const { return false; } |
|---|
| 382 | |
|---|
| 383 | /** do customized cull code, return true if drawable should be culled.*/ |
|---|
| 384 | virtual bool cull(osg::NodeVisitor* nv, osg::Drawable* drawable, osg::RenderInfo* renderInfo) const { return cull(nv, drawable, renderInfo? renderInfo->getState():0); } |
|---|
| 385 | }; |
|---|
| 386 | |
|---|
| 387 | /** Set the CullCallback which allows users to customize the culling of Drawable during the cull traversal.*/ |
|---|
| 388 | virtual void setCullCallback(CullCallback* cc) { _cullCallback=cc; } |
|---|
| 389 | |
|---|
| 390 | /** Get the non const CullCallback.*/ |
|---|
| 391 | CullCallback* getCullCallback() { return _cullCallback.get(); } |
|---|
| 392 | |
|---|
| 393 | /** Get the const CullCallback.*/ |
|---|
| 394 | const CullCallback* getCullCallback() const { return _cullCallback.get(); } |
|---|
| 395 | |
|---|
| 396 | |
|---|
| 397 | |
|---|
| 398 | |
|---|
| 399 | /** Callback attached to an Drawable which allows the users to customize the drawing of an exist Drawable object. |
|---|
| 400 | * The draw callback is implement as a replacement to the Drawable's own drawImplementation() method, if the |
|---|
| 401 | * the user intends to decorate the existing draw code then simple call the drawable->drawImplementation() from |
|---|
| 402 | * with the callbacks drawImplementation() method. This allows the users to do both pre and post callbacks |
|---|
| 403 | * without fuss and can even disable the inner draw if required.*/ |
|---|
| 404 | struct DrawCallback : public virtual osg::Object |
|---|
| 405 | { |
|---|
| 406 | DrawCallback() {} |
|---|
| 407 | |
|---|
| 408 | DrawCallback(const DrawCallback&,const CopyOp&) {} |
|---|
| 409 | |
|---|
| 410 | META_Object(osg,DrawCallback); |
|---|
| 411 | |
|---|
| 412 | /** do customized draw code.*/ |
|---|
| 413 | virtual void drawImplementation(osg::RenderInfo& /*renderInfo*/,const osg::Drawable* /*drawable*/) const {} |
|---|
| 414 | }; |
|---|
| 415 | |
|---|
| 416 | /** Set the DrawCallback which allows users to attach customize the drawing of existing Drawable object.*/ |
|---|
| 417 | virtual void setDrawCallback(DrawCallback* dc) { _drawCallback=dc; dirtyDisplayList(); } |
|---|
| 418 | |
|---|
| 419 | /** Get the non const DrawCallback.*/ |
|---|
| 420 | DrawCallback* getDrawCallback() { return _drawCallback.get(); } |
|---|
| 421 | |
|---|
| 422 | /** Get the const DrawCallback.*/ |
|---|
| 423 | const DrawCallback* getDrawCallback() const { return _drawCallback.get(); } |
|---|
| 424 | |
|---|
| 425 | /** drawImplementation(RenderInfo&) is a pure virtual method for the actual implementation of OpenGL drawing calls, such as vertex arrays and primitives, that |
|---|
| 426 | * must be implemented in concrete subclasses of the Drawable base class, examples include osg::Geometry and osg::ShapeDrawable. |
|---|
| 427 | * drawImplementation(RenderInfo&) is called from the draw(RenderInfo&) method, with the draw method handling management of OpenGL display lists, |
|---|
| 428 | * and drawImplementation(RenderInfo&) handling the actual drawing itself. |
|---|
| 429 | * @param renderInfo The osg::RenderInfo object that encapsulates the current rendering information including the osg::State OpenGL state for the current graphics context. */ |
|---|
| 430 | virtual void drawImplementation(RenderInfo& renderInfo) const = 0; |
|---|
| 431 | |
|---|
| 432 | |
|---|
| 433 | /** Return a OpenGL display list handle a newly generated or reused from display list cache. */ |
|---|
| 434 | static GLuint generateDisplayList(unsigned int contextID, unsigned int sizeHint = 0); |
|---|
| 435 | |
|---|
| 436 | /** Set the minimum number of display lists to retain in the deleted display list cache. */ |
|---|
| 437 | static void setMinimumNumberOfDisplayListsToRetainInCache(unsigned int minimum); |
|---|
| 438 | |
|---|
| 439 | /** Get the minimum number of display lists to retain in the deleted display list cache. */ |
|---|
| 440 | static unsigned int getMinimumNumberOfDisplayListsToRetainInCache(); |
|---|
| 441 | |
|---|
| 442 | /** Use deleteDisplayList instead of glDeleteList to allow |
|---|
| 443 | * OpenGL display list to be cached until they can be deleted |
|---|
| 444 | * by the OpenGL context in which they were created, specified |
|---|
| 445 | * by contextID.*/ |
|---|
| 446 | static void deleteDisplayList(unsigned int contextID,GLuint globj, unsigned int sizeHint = 0); |
|---|
| 447 | |
|---|
| 448 | /** Flush all the cached display list which need to be deleted |
|---|
| 449 | * in the OpenGL context related to contextID.*/ |
|---|
| 450 | static void flushAllDeletedDisplayLists(unsigned int contextID); |
|---|
| 451 | |
|---|
| 452 | /** Flush all the cached display list which need to be deleted |
|---|
| 453 | * in the OpenGL context related to contextID. |
|---|
| 454 | * Note, unlike flush no OpenGL calls are made, instead the handles are all removed. |
|---|
| 455 | * this call is useful for when an OpenGL context has been destroyed. */ |
|---|
| 456 | static void discardAllDeletedDisplayLists(unsigned int contextID); |
|---|
| 457 | |
|---|
| 458 | /** Flush the cached display list which need to be deleted |
|---|
| 459 | * in the OpenGL context related to contextID.*/ |
|---|
| 460 | static void flushDeletedDisplayLists(unsigned int contextID,double& availableTime); |
|---|
| 461 | |
|---|
| 462 | typedef unsigned int AttributeType; |
|---|
| 463 | |
|---|
| 464 | enum AttributeTypes |
|---|
| 465 | { |
|---|
| 466 | VERTICES = 0, |
|---|
| 467 | WEIGHTS = 1, |
|---|
| 468 | NORMALS = 2, |
|---|
| 469 | COLORS = 3, |
|---|
| 470 | SECONDARY_COLORS = 4, |
|---|
| 471 | FOG_COORDS = 5, |
|---|
| 472 | ATTRIBUTE_6 = 6, |
|---|
| 473 | ATTRIBUTE_7 = 7, |
|---|
| 474 | TEXTURE_COORDS = 8, |
|---|
| 475 | TEXTURE_COORDS_0 = TEXTURE_COORDS, |
|---|
| 476 | TEXTURE_COORDS_1 = TEXTURE_COORDS_0+1, |
|---|
| 477 | TEXTURE_COORDS_2 = TEXTURE_COORDS_0+2, |
|---|
| 478 | TEXTURE_COORDS_3 = TEXTURE_COORDS_0+3, |
|---|
| 479 | TEXTURE_COORDS_4 = TEXTURE_COORDS_0+4, |
|---|
| 480 | TEXTURE_COORDS_5 = TEXTURE_COORDS_0+5, |
|---|
| 481 | TEXTURE_COORDS_6 = TEXTURE_COORDS_0+6, |
|---|
| 482 | TEXTURE_COORDS_7 = TEXTURE_COORDS_0+7 |
|---|
| 483 | // only eight texture coord examples provided here, but underlying code can handle any no of texture units, |
|---|
| 484 | // simply co them as (TEXTURE_COORDS_0+unit). |
|---|
| 485 | }; |
|---|
| 486 | |
|---|
| 487 | class AttributeFunctor |
|---|
| 488 | { |
|---|
| 489 | public: |
|---|
| 490 | virtual ~AttributeFunctor() {} |
|---|
| 491 | |
|---|
| 492 | virtual void apply(AttributeType,unsigned int,GLbyte*) {} |
|---|
| 493 | virtual void apply(AttributeType,unsigned int,GLshort*) {} |
|---|
| 494 | virtual void apply(AttributeType,unsigned int,GLint*) {} |
|---|
| 495 | |
|---|
| 496 | virtual void apply(AttributeType,unsigned int,GLubyte*) {} |
|---|
| 497 | virtual void apply(AttributeType,unsigned int,GLushort*) {} |
|---|
| 498 | virtual void apply(AttributeType,unsigned int,GLuint*) {} |
|---|
| 499 | |
|---|
| 500 | virtual void apply(AttributeType,unsigned int,float*) {} |
|---|
| 501 | virtual void apply(AttributeType,unsigned int,Vec2*) {} |
|---|
| 502 | virtual void apply(AttributeType,unsigned int,Vec3*) {} |
|---|
| 503 | virtual void apply(AttributeType,unsigned int,Vec4*) {} |
|---|
| 504 | virtual void apply(AttributeType,unsigned int,Vec4ub*) {} |
|---|
| 505 | |
|---|
| 506 | virtual void apply(AttributeType,unsigned int,double*) {} |
|---|
| 507 | virtual void apply(AttributeType,unsigned int,Vec2d*) {} |
|---|
| 508 | virtual void apply(AttributeType,unsigned int,Vec3d*) {} |
|---|
| 509 | virtual void apply(AttributeType,unsigned int,Vec4d*) {} |
|---|
| 510 | }; |
|---|
| 511 | |
|---|
| 512 | |
|---|
| 513 | /** Return true if the Drawable subclass supports accept(AttributeFunctor&).*/ |
|---|
| 514 | virtual bool supports(const AttributeFunctor&) const { return false; } |
|---|
| 515 | |
|---|
| 516 | /** accept an AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. |
|---|
| 517 | * return true if functor handled by drawable, |
|---|
| 518 | * return false on failure of drawable to generate functor calls.*/ |
|---|
| 519 | virtual void accept(AttributeFunctor&) {} |
|---|
| 520 | |
|---|
| 521 | |
|---|
| 522 | class ConstAttributeFunctor |
|---|
| 523 | { |
|---|
| 524 | public: |
|---|
| 525 | |
|---|
| 526 | virtual ~ConstAttributeFunctor() {} |
|---|
| 527 | |
|---|
| 528 | virtual void apply(AttributeType,unsigned int,const GLbyte*) {} |
|---|
| 529 | virtual void apply(AttributeType,unsigned int,const GLshort*) {} |
|---|
| 530 | virtual void apply(AttributeType,unsigned int,const GLint*) {} |
|---|
| 531 | |
|---|
| 532 | virtual void apply(AttributeType,unsigned int,const GLubyte*) {} |
|---|
| 533 | virtual void apply(AttributeType,unsigned int,const GLushort*) {} |
|---|
| 534 | virtual void apply(AttributeType,unsigned int,const GLuint*) {} |
|---|
| 535 | |
|---|
| 536 | virtual void apply(AttributeType,unsigned int,const float*) {} |
|---|
| 537 | virtual void apply(AttributeType,unsigned int,const Vec2*) {} |
|---|
| 538 | virtual void apply(AttributeType,unsigned int,const Vec3*) {} |
|---|
| 539 | virtual void apply(AttributeType,unsigned int,const Vec4*) {} |
|---|
| 540 | virtual void apply(AttributeType,unsigned int,const Vec4ub*) {} |
|---|
| 541 | |
|---|
| 542 | virtual void apply(AttributeType,unsigned int,const double*) {} |
|---|
| 543 | virtual void apply(AttributeType,unsigned int,const Vec2d*) {} |
|---|
| 544 | virtual void apply(AttributeType,unsigned int,const Vec3d*) {} |
|---|
| 545 | virtual void apply(AttributeType,unsigned int,const Vec4d*) {} |
|---|
| 546 | }; |
|---|
| 547 | |
|---|
| 548 | /** Return true if the Drawable subclass supports accept(ConstAttributeFunctor&).*/ |
|---|
| 549 | virtual bool supports(const ConstAttributeFunctor&) const { return false; } |
|---|
| 550 | |
|---|
| 551 | /** Accept an AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. |
|---|
| 552 | * return true if functor handled by drawable, |
|---|
| 553 | * return false on failure of drawable to generate functor calls.*/ |
|---|
| 554 | virtual void accept(ConstAttributeFunctor&) const {} |
|---|
| 555 | |
|---|
| 556 | |
|---|
| 557 | |
|---|
| 558 | /** Return true if the Drawable subclass supports accept(PrimitiveFunctor&).*/ |
|---|
| 559 | virtual bool supports(const PrimitiveFunctor&) const { return false; } |
|---|
| 560 | |
|---|
| 561 | /** Accept a PrimitiveFunctor and call its methods to tell it about the internal primitives that this Drawable has. |
|---|
| 562 | * return true if functor handled by drawable, return false on failure of drawable to generate functor calls. |
|---|
| 563 | * Note, PrimtiveFunctor only provides const access of the primitives, as primitives may be procedurally generated |
|---|
| 564 | * so one cannot modify it.*/ |
|---|
| 565 | virtual void accept(PrimitiveFunctor&) const {} |
|---|
| 566 | |
|---|
| 567 | /** Return true if the Drawable subclass supports accept(PrimitiveIndexFunctor&).*/ |
|---|
| 568 | virtual bool supports(const PrimitiveIndexFunctor&) const { return false; } |
|---|
| 569 | |
|---|
| 570 | /** Accept a PrimitiveIndexFunctor and call its methods to tell it about the internal primitives that this Drawable has. |
|---|
| 571 | * return true if functor handled by drawable, return false on failure of drawable to generate functor calls. |
|---|
| 572 | * Note, PrimtiveIndexFunctor only provide const access of the primitives, as primitives may be procedurally generated |
|---|
| 573 | * so one cannot modify it.*/ |
|---|
| 574 | virtual void accept(PrimitiveIndexFunctor&) const {} |
|---|
| 575 | |
|---|
| 576 | |
|---|
| 577 | /** Extensions class which encapsulates the querying of extensions and |
|---|
| 578 | * associated function pointers, and provide convenience wrappers to |
|---|
| 579 | * check for the extensions or use the associated functions.*/ |
|---|
| 580 | class OSG_EXPORT Extensions : public osg::Referenced |
|---|
| 581 | { |
|---|
| 582 | public: |
|---|
| 583 | Extensions(unsigned int contextID); |
|---|
| 584 | |
|---|
| 585 | Extensions(const Extensions& rhs); |
|---|
| 586 | |
|---|
| 587 | void lowestCommonDenominator(const Extensions& rhs); |
|---|
| 588 | |
|---|
| 589 | void setupGLExtensions(unsigned int contextID); |
|---|
| 590 | |
|---|
| 591 | void setVertexProgramSupported(bool flag) { _isVertexProgramSupported=flag; } |
|---|
| 592 | bool isVertexProgramSupported() const { return _isVertexProgramSupported; } |
|---|
| 593 | |
|---|
| 594 | void setSecondaryColorSupported(bool flag) { _isSecondaryColorSupported=flag; } |
|---|
| 595 | bool isSecondaryColorSupported() const { return _isSecondaryColorSupported; } |
|---|
| 596 | |
|---|
| 597 | void setFogCoordSupported(bool flag) { _isFogCoordSupported=flag; } |
|---|
| 598 | bool isFogCoordSupported() const { return _isFogCoordSupported; } |
|---|
| 599 | |
|---|
| 600 | void setMultiTexSupported(bool flag) { _isMultiTexSupported=flag; } |
|---|
| 601 | bool isMultiTexSupported() const { return _isMultiTexSupported; } |
|---|
| 602 | |
|---|
| 603 | void setOcclusionQuerySupported(bool flag) { _isOcclusionQuerySupported=flag; } |
|---|
| 604 | bool isOcclusionQuerySupported() const { return _isOcclusionQuerySupported; } |
|---|
| 605 | |
|---|
| 606 | void setARBOcclusionQuerySupported(bool flag) { _isARBOcclusionQuerySupported=flag; } |
|---|
| 607 | bool isARBOcclusionQuerySupported() const { return _isARBOcclusionQuerySupported; } |
|---|
| 608 | |
|---|
| 609 | void setTimerQuerySupported(bool flag) { _isTimerQuerySupported = flag; } |
|---|
| 610 | bool isTimerQuerySupported() const { return _isTimerQuerySupported; } |
|---|
| 611 | void setARBTimerQuerySupported(bool flag) { _isARBTimerQuerySupported = flag; } |
|---|
| 612 | bool isARBTimerQuerySupported() const { return _isARBTimerQuerySupported; } |
|---|
| 613 | void glSecondaryColor3ubv(const GLubyte* coord) const; |
|---|
| 614 | void glSecondaryColor3fv(const GLfloat* coord) const; |
|---|
| 615 | |
|---|
| 616 | void glFogCoordfv(const GLfloat* coord) const; |
|---|
| 617 | |
|---|
| 618 | void glMultiTexCoord1f(GLenum target,GLfloat coord) const; |
|---|
| 619 | void glMultiTexCoord2fv(GLenum target,const GLfloat* coord) const; |
|---|
| 620 | void glMultiTexCoord3fv(GLenum target,const GLfloat* coord) const; |
|---|
| 621 | void glMultiTexCoord4fv(GLenum target,const GLfloat* coord) const; |
|---|
| 622 | |
|---|
| 623 | void glMultiTexCoord1d(GLenum target,GLdouble coord) const; |
|---|
| 624 | void glMultiTexCoord2dv(GLenum target,const GLdouble* coord) const; |
|---|
| 625 | void glMultiTexCoord3dv(GLenum target,const GLdouble* coord) const; |
|---|
| 626 | void glMultiTexCoord4dv(GLenum target,const GLdouble* coord) const; |
|---|
| 627 | |
|---|
| 628 | void glVertexAttrib1s(unsigned int index, GLshort s) const; |
|---|
| 629 | void glVertexAttrib1f(unsigned int index, GLfloat f) const; |
|---|
| 630 | void glVertexAttrib1d(unsigned int index, GLdouble f) const; |
|---|
| 631 | void glVertexAttrib2fv(unsigned int index, const GLfloat * v) const; |
|---|
| 632 | void glVertexAttrib3fv(unsigned int index, const GLfloat * v) const; |
|---|
| 633 | void glVertexAttrib4fv(unsigned int index, const GLfloat * v) const; |
|---|
| 634 | void glVertexAttrib2dv(unsigned int index, const GLdouble * v) const; |
|---|
| 635 | void glVertexAttrib3dv(unsigned int index, const GLdouble * v) const; |
|---|
| 636 | void glVertexAttrib4dv(unsigned int index, const GLdouble * v) const; |
|---|
| 637 | void glVertexAttrib4ubv(unsigned int index, const GLubyte * v) const; |
|---|
| 638 | void glVertexAttrib4Nubv(unsigned int index, const GLubyte * v) const; |
|---|
| 639 | |
|---|
| 640 | |
|---|
| 641 | void glGenBuffers (GLsizei n, GLuint *buffers) const; |
|---|
| 642 | void glBindBuffer (GLenum target, GLuint buffer) const; |
|---|
| 643 | void glBufferData (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage) const; |
|---|
| 644 | void glBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data) const; |
|---|
| 645 | void glDeleteBuffers (GLsizei n, const GLuint *buffers) const; |
|---|
| 646 | GLboolean glIsBuffer (GLuint buffer) const; |
|---|
| 647 | void glGetBufferSubData (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data) const; |
|---|
| 648 | GLvoid* glMapBuffer (GLenum target, GLenum access) const; |
|---|
| 649 | GLboolean glUnmapBuffer (GLenum target) const; |
|---|
| 650 | void glGetBufferParameteriv (GLenum target, GLenum pname, GLint *params) const; |
|---|
| 651 | void glGetBufferPointerv (GLenum target, GLenum pname, GLvoid* *params) const; |
|---|
| 652 | |
|---|
| 653 | |
|---|
| 654 | void glGenOcclusionQueries( GLsizei n, GLuint *ids ) const; |
|---|
| 655 | void glDeleteOcclusionQueries( GLsizei n, const GLuint *ids ) const; |
|---|
| 656 | GLboolean glIsOcclusionQuery( GLuint id ) const; |
|---|
| 657 | void glBeginOcclusionQuery( GLuint id ) const; |
|---|
| 658 | void glEndOcclusionQuery() const; |
|---|
| 659 | void glGetOcclusionQueryiv( GLuint id, GLenum pname, GLint *params ) const; |
|---|
| 660 | void glGetOcclusionQueryuiv( GLuint id, GLenum pname, GLuint *params ) const; |
|---|
| 661 | |
|---|
| 662 | void glGetQueryiv(GLenum target, GLenum pname, GLint *params) const; |
|---|
| 663 | void glGenQueries(GLsizei n, GLuint *ids) const; |
|---|
| 664 | void glBeginQuery(GLenum target, GLuint id) const; |
|---|
| 665 | void glEndQuery(GLenum target) const; |
|---|
| 666 | void glQueryCounter(GLuint id, GLenum target) const; |
|---|
| 667 | GLboolean glIsQuery(GLuint id) const; |
|---|
| 668 | void glDeleteQueries(GLsizei n, const GLuint *ids) const; |
|---|
| 669 | void glGetQueryObjectiv(GLuint id, GLenum pname, GLint *params) const; |
|---|
| 670 | void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params) const; |
|---|
| 671 | void glGetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params) const; |
|---|
| 672 | void glGetInteger64v(GLenum pname, GLint64EXT *params) const; |
|---|
| 673 | |
|---|
| 674 | protected: |
|---|
| 675 | |
|---|
| 676 | friend class ArrayDispatchers; |
|---|
| 677 | |
|---|
| 678 | typedef void (GL_APIENTRY * FogCoordProc) (const GLfloat* coord); |
|---|
| 679 | |
|---|
| 680 | typedef void (GL_APIENTRY * VertexAttrib1sProc) (GLuint index, GLshort s); |
|---|
| 681 | typedef void (GL_APIENTRY * VertexAttrib1fProc) (GLuint index, GLfloat f); |
|---|
| 682 | typedef void (GL_APIENTRY * VertexAttrib1dProc) (GLuint index, GLdouble f); |
|---|
| 683 | typedef void (GL_APIENTRY * VertexAttribfvProc) (GLuint index, const GLfloat * v); |
|---|
| 684 | typedef void (GL_APIENTRY * VertexAttribdvProc) (GLuint index, const GLdouble * v); |
|---|
| 685 | typedef void (GL_APIENTRY * VertexAttribubvProc) (GLuint index, const GLubyte * v); |
|---|
| 686 | |
|---|
| 687 | typedef void (GL_APIENTRY * SecondaryColor3ubvProc) (const GLubyte* coord); |
|---|
| 688 | typedef void (GL_APIENTRY * SecondaryColor3fvProc) (const GLfloat* coord); |
|---|
| 689 | |
|---|
| 690 | typedef void (GL_APIENTRY * MultiTexCoord1fProc) (GLenum target,GLfloat coord); |
|---|
| 691 | typedef void (GL_APIENTRY * MultiTexCoordfvProc) (GLenum target,const GLfloat* coord); |
|---|
| 692 | typedef void (GL_APIENTRY * MultiTexCoord1dProc) (GLenum target,GLdouble coord); |
|---|
| 693 | typedef void (GL_APIENTRY * MultiTexCoorddvProc) (GLenum target,const GLdouble* coord); |
|---|
| 694 | |
|---|
| 695 | |
|---|
| 696 | typedef void (GL_APIENTRY * GenBuffersProc) (GLsizei n, GLuint *buffers); |
|---|
| 697 | typedef void (GL_APIENTRY * BindBufferProc) (GLenum target, GLuint buffer); |
|---|
| 698 | typedef void (GL_APIENTRY * BufferDataProc) (GLenum target, GLsizeiptrARB size, const GLvoid *data, GLenum usage); |
|---|
| 699 | typedef void (GL_APIENTRY * BufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, const GLvoid *data); |
|---|
| 700 | typedef void (GL_APIENTRY * DeleteBuffersProc) (GLsizei n, const GLuint *buffers); |
|---|
| 701 | typedef GLboolean (GL_APIENTRY * IsBufferProc) (GLuint buffer); |
|---|
| 702 | typedef void (GL_APIENTRY * GetBufferSubDataProc) (GLenum target, GLintptrARB offset, GLsizeiptrARB size, GLvoid *data); |
|---|
| 703 | typedef GLvoid* (GL_APIENTRY * MapBufferProc) (GLenum target, GLenum access); |
|---|
| 704 | typedef GLboolean (GL_APIENTRY * UnmapBufferProc) (GLenum target); |
|---|
| 705 | typedef void (GL_APIENTRY * GetBufferParameterivProc) (GLenum target, GLenum pname, GLint *params); |
|---|
| 706 | typedef void (GL_APIENTRY * GetBufferPointervProc) (GLenum target, GLenum pname, GLvoid* *params); |
|---|
| 707 | |
|---|
| 708 | typedef void (GL_APIENTRY * GenOcclusionQueriesProc) ( GLsizei n, GLuint *ids ); |
|---|
| 709 | typedef void (GL_APIENTRY * DeleteOcclusionQueriesProc) ( GLsizei n, const GLuint *ids ); |
|---|
| 710 | typedef GLboolean (GL_APIENTRY * IsOcclusionQueryProc) ( GLuint id ); |
|---|
| 711 | typedef void (GL_APIENTRY * BeginOcclusionQueryProc) ( GLuint id ); |
|---|
| 712 | typedef void (GL_APIENTRY * EndOcclusionQueryProc) (); |
|---|
| 713 | typedef void (GL_APIENTRY * GetOcclusionQueryivProc) ( GLuint id, GLenum pname, GLint *params ); |
|---|
| 714 | typedef void (GL_APIENTRY * GetOcclusionQueryuivProc) ( GLuint id, GLenum pname, GLuint *params ); |
|---|
| 715 | typedef void (GL_APIENTRY * GetOcclusionQueryui64vProc) ( GLuint id, GLenum pname, GLuint64EXT *params ); |
|---|
| 716 | |
|---|
| 717 | typedef void (GL_APIENTRY *GenQueriesProc) (GLsizei n, GLuint *ids); |
|---|
| 718 | typedef void (GL_APIENTRY *DeleteQueriesProc) (GLsizei n, const GLuint *ids); |
|---|
| 719 | typedef GLboolean (GL_APIENTRY *IsQueryProc) (GLuint id); |
|---|
| 720 | typedef void (GL_APIENTRY *BeginQueryProc) (GLenum target, GLuint id); |
|---|
| 721 | typedef void (GL_APIENTRY *EndQueryProc) (GLenum target); |
|---|
| 722 | typedef void (GL_APIENTRY *QueryCounterProc)(GLuint id, GLenum target); |
|---|
| 723 | typedef void (GL_APIENTRY *GetQueryivProc) (GLenum target, GLenum pname, GLint *params); |
|---|
| 724 | typedef void (GL_APIENTRY *GetQueryObjectivProc) (GLuint id, GLenum pname, GLint *params); |
|---|
| 725 | typedef void (GL_APIENTRY *GetQueryObjectuivProc) (GLuint id, GLenum pname, GLuint *params); |
|---|
| 726 | typedef void (GL_APIENTRY *GetQueryObjectui64vProc) (GLuint id, GLenum pname, GLuint64EXT *params); |
|---|
| 727 | typedef void (GL_APIENTRY *GetInteger64vProc) (GLenum pname, GLint64EXT *params); |
|---|
| 728 | |
|---|
| 729 | ~Extensions() {} |
|---|
| 730 | |
|---|
| 731 | bool _isVertexProgramSupported; |
|---|
| 732 | bool _isSecondaryColorSupported; |
|---|
| 733 | bool _isFogCoordSupported; |
|---|
| 734 | bool _isMultiTexSupported; |
|---|
| 735 | bool _isOcclusionQuerySupported; |
|---|
| 736 | bool _isARBOcclusionQuerySupported; |
|---|
| 737 | bool _isTimerQuerySupported; |
|---|
| 738 | bool _isARBTimerQuerySupported; |
|---|
| 739 | |
|---|
| 740 | FogCoordProc _glFogCoordfv; |
|---|
| 741 | |
|---|
| 742 | SecondaryColor3ubvProc _glSecondaryColor3ubv; |
|---|
| 743 | SecondaryColor3fvProc _glSecondaryColor3fv; |
|---|
| 744 | |
|---|
| 745 | VertexAttrib1sProc _glVertexAttrib1s; |
|---|
| 746 | VertexAttrib1fProc _glVertexAttrib1f; |
|---|
| 747 | VertexAttrib1dProc _glVertexAttrib1d; |
|---|
| 748 | VertexAttribfvProc _glVertexAttrib1fv; |
|---|
| 749 | VertexAttribfvProc _glVertexAttrib2fv; |
|---|
| 750 | VertexAttribfvProc _glVertexAttrib3fv; |
|---|
| 751 | VertexAttribfvProc _glVertexAttrib4fv; |
|---|
| 752 | VertexAttribdvProc _glVertexAttrib2dv; |
|---|
| 753 | VertexAttribdvProc _glVertexAttrib3dv; |
|---|
| 754 | VertexAttribdvProc _glVertexAttrib4dv; |
|---|
| 755 | VertexAttribubvProc _glVertexAttrib4ubv; |
|---|
| 756 | VertexAttribubvProc _glVertexAttrib4Nubv; |
|---|
| 757 | |
|---|
| 758 | MultiTexCoord1fProc _glMultiTexCoord1f; |
|---|
| 759 | MultiTexCoordfvProc _glMultiTexCoord1fv; |
|---|
| 760 | MultiTexCoordfvProc _glMultiTexCoord2fv; |
|---|
| 761 | MultiTexCoordfvProc _glMultiTexCoord3fv; |
|---|
| 762 | MultiTexCoordfvProc _glMultiTexCoord4fv; |
|---|
| 763 | MultiTexCoord1dProc _glMultiTexCoord1d; |
|---|
| 764 | MultiTexCoorddvProc _glMultiTexCoord2dv; |
|---|
| 765 | MultiTexCoorddvProc _glMultiTexCoord3dv; |
|---|
| 766 | MultiTexCoorddvProc _glMultiTexCoord4dv; |
|---|
| 767 | |
|---|
| 768 | GenBuffersProc _glGenBuffers; |
|---|
| 769 | BindBufferProc _glBindBuffer; |
|---|
| 770 | BufferDataProc _glBufferData; |
|---|
| 771 | BufferSubDataProc _glBufferSubData; |
|---|
| 772 | DeleteBuffersProc _glDeleteBuffers; |
|---|
| 773 | IsBufferProc _glIsBuffer; |
|---|
| 774 | GetBufferSubDataProc _glGetBufferSubData; |
|---|
| 775 | MapBufferProc _glMapBuffer; |
|---|
| 776 | UnmapBufferProc _glUnmapBuffer; |
|---|
| 777 | GetBufferParameterivProc _glGetBufferParameteriv; |
|---|
| 778 | GetBufferPointervProc _glGetBufferPointerv; |
|---|
| 779 | |
|---|
| 780 | GenOcclusionQueriesProc _glGenOcclusionQueries; |
|---|
| 781 | DeleteOcclusionQueriesProc _glDeleteOcclusionQueries; |
|---|
| 782 | IsOcclusionQueryProc _glIsOcclusionQuery; |
|---|
| 783 | BeginOcclusionQueryProc _glBeginOcclusionQuery; |
|---|
| 784 | EndOcclusionQueryProc _glEndOcclusionQuery; |
|---|
| 785 | GetOcclusionQueryivProc _glGetOcclusionQueryiv; |
|---|
| 786 | GetOcclusionQueryuivProc _glGetOcclusionQueryuiv; |
|---|
| 787 | |
|---|
| 788 | GenQueriesProc _gl_gen_queries_arb; |
|---|
| 789 | DeleteQueriesProc _gl_delete_queries_arb; |
|---|
| 790 | IsQueryProc _gl_is_query_arb; |
|---|
| 791 | BeginQueryProc _gl_begin_query_arb; |
|---|
| 792 | EndQueryProc _gl_end_query_arb; |
|---|
| 793 | QueryCounterProc _glQueryCounter; |
|---|
| 794 | GetQueryivProc _gl_get_queryiv_arb; |
|---|
| 795 | GetQueryObjectivProc _gl_get_query_objectiv_arb; |
|---|
| 796 | GetQueryObjectuivProc _gl_get_query_objectuiv_arb; |
|---|
| 797 | GetQueryObjectui64vProc _gl_get_query_objectui64v; |
|---|
| 798 | GetInteger64vProc _glGetInteger64v; |
|---|
| 799 | |
|---|
| 800 | }; |
|---|
| 801 | |
|---|
| 802 | /** Function to call to get the extension of a specified context. |
|---|
| 803 | * If the Extension object for that context has not yet been created |
|---|
| 804 | * and the 'createIfNotInitalized' flag been set to false then returns NULL. |
|---|
| 805 | * If 'createIfNotInitalized' is true then the Extensions object is |
|---|
| 806 | * automatically created. However, in this case the extension object is |
|---|
| 807 | * only created with the graphics context associated with ContextID..*/ |
|---|
| 808 | static Extensions* getExtensions(unsigned int contextID,bool createIfNotInitalized); |
|---|
| 809 | |
|---|
| 810 | /** setExtensions allows users to override the extensions across graphics contexts. |
|---|
| 811 | * typically used when you have different extensions supported across graphics pipes |
|---|
| 812 | * but need to ensure that they all use the same low common denominator extensions.*/ |
|---|
| 813 | static void setExtensions(unsigned int contextID,Extensions* extensions); |
|---|
| 814 | |
|---|
| 815 | |
|---|
| 816 | protected: |
|---|
| 817 | |
|---|
| 818 | Drawable& operator = (const Drawable&) { return *this;} |
|---|
| 819 | |
|---|
| 820 | virtual ~Drawable(); |
|---|
| 821 | |
|---|
| 822 | |
|---|
| 823 | /** set the bounding box .*/ |
|---|
| 824 | void setBound(const BoundingBox& bb) const; |
|---|
| 825 | |
|---|
| 826 | void addParent(osg::Node* node); |
|---|
| 827 | void removeParent(osg::Node* node); |
|---|
| 828 | |
|---|
| 829 | ParentList _parents; |
|---|
| 830 | friend class Node; |
|---|
| 831 | friend class Geode; |
|---|
| 832 | friend class StateSet; |
|---|
| 833 | |
|---|
| 834 | ref_ptr<StateSet> _stateset; |
|---|
| 835 | |
|---|
| 836 | BoundingBox _initialBound; |
|---|
| 837 | ref_ptr<ComputeBoundingBoxCallback> _computeBoundCallback; |
|---|
| 838 | mutable BoundingBox _boundingBox; |
|---|
| 839 | mutable bool _boundingBoxComputed; |
|---|
| 840 | |
|---|
| 841 | ref_ptr<Shape> _shape; |
|---|
| 842 | |
|---|
| 843 | bool _supportsDisplayList; |
|---|
| 844 | bool _useDisplayList; |
|---|
| 845 | bool _supportsVertexBufferObjects; |
|---|
| 846 | bool _useVertexBufferObjects; |
|---|
| 847 | |
|---|
| 848 | typedef osg::buffered_value<GLuint> GLObjectList; |
|---|
| 849 | mutable GLObjectList _globjList; |
|---|
| 850 | |
|---|
| 851 | ref_ptr<UpdateCallback> _updateCallback; |
|---|
| 852 | unsigned int _numChildrenRequiringUpdateTraversal; |
|---|
| 853 | void setNumChildrenRequiringUpdateTraversal(unsigned int num); |
|---|
| 854 | unsigned int getNumChildrenRequiringUpdateTraversal() const { return _numChildrenRequiringUpdateTraversal; } |
|---|
| 855 | |
|---|
| 856 | ref_ptr<EventCallback> _eventCallback; |
|---|
| 857 | unsigned int _numChildrenRequiringEventTraversal; |
|---|
| 858 | void setNumChildrenRequiringEventTraversal(unsigned int num); |
|---|
| 859 | unsigned int getNumChildrenRequiringEventTraversal() const { return _numChildrenRequiringEventTraversal; } |
|---|
| 860 | |
|---|
| 861 | ref_ptr<CullCallback> _cullCallback; |
|---|
| 862 | ref_ptr<DrawCallback> _drawCallback; |
|---|
| 863 | }; |
|---|
| 864 | |
|---|
| 865 | inline void Drawable::draw(RenderInfo& renderInfo) const |
|---|
| 866 | { |
|---|
| 867 | #ifdef OSG_GL_DISPLAYLISTS_AVAILABLE |
|---|
| 868 | if (_useDisplayList && !(_supportsVertexBufferObjects && _useVertexBufferObjects && renderInfo.getState()->isVertexBufferObjectSupported())) |
|---|
| 869 | { |
|---|
| 870 | // get the contextID (user defined ID of 0 upwards) for the |
|---|
| 871 | // current OpenGL context. |
|---|
| 872 | unsigned int contextID = renderInfo.getContextID(); |
|---|
| 873 | |
|---|
| 874 | // get the globj for the current contextID. |
|---|
| 875 | GLuint& globj = _globjList[contextID]; |
|---|
| 876 | |
|---|
| 877 | // call the globj if already set otherwise compile and execute. |
|---|
| 878 | if( globj != 0 ) |
|---|
| 879 | { |
|---|
| 880 | glCallList( globj ); |
|---|
| 881 | } |
|---|
| 882 | else if (_useDisplayList) |
|---|
| 883 | { |
|---|
| 884 | #ifdef USE_SEPARATE_COMPILE_AND_EXECUTE |
|---|
| 885 | globj = generateDisplayList(contextID, getGLObjectSizeHint()); |
|---|
| 886 | glNewList( globj, GL_COMPILE ); |
|---|
| 887 | if (_drawCallback.valid()) |
|---|
| 888 | _drawCallback->drawImplementation(renderInfo,this); |
|---|
| 889 | else |
|---|
| 890 | drawImplementation(renderInfo); |
|---|
| 891 | glEndList(); |
|---|
| 892 | |
|---|
| 893 | glCallList( globj); |
|---|
| 894 | #else |
|---|
| 895 | globj = generateDisplayList(contextID, getGLObjectSizeHint()); |
|---|
| 896 | glNewList( globj, GL_COMPILE_AND_EXECUTE ); |
|---|
| 897 | if (_drawCallback.valid()) |
|---|
| 898 | _drawCallback->drawImplementation(renderInfo,this); |
|---|
| 899 | else |
|---|
| 900 | drawImplementation(renderInfo); |
|---|
| 901 | glEndList(); |
|---|
| 902 | #endif |
|---|
| 903 | } |
|---|
| 904 | |
|---|
| 905 | return; |
|---|
| 906 | |
|---|
| 907 | } |
|---|
| 908 | #endif |
|---|
| 909 | |
|---|
| 910 | // draw object as nature intended.. |
|---|
| 911 | if (_drawCallback.valid()) |
|---|
| 912 | _drawCallback->drawImplementation(renderInfo,this); |
|---|
| 913 | else |
|---|
| 914 | drawImplementation(renderInfo); |
|---|
| 915 | } |
|---|
| 916 | |
|---|
| 917 | |
|---|
| 918 | } |
|---|
| 919 | |
|---|
| 920 | #endif |
|---|