/* -*-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_GEOMETRY #define OSG_GEOMETRY 1 #include #include #include #include #include #include // leave defined for OpenSceneGraph-3.2 release, post 3.2 associated methods will be only be available in deprecated_osg::Geometry #define OSG_DEPRECATED_GEOMETRY_BINDING 1 namespace osg { class OSG_EXPORT Geometry : public Drawable { public: Geometry(); /** Copy constructor using CopyOp to manage deep vs shallow copy. */ Geometry(const Geometry& geometry,const CopyOp& copyop=CopyOp::SHALLOW_COPY); META_Node(osg, Geometry); virtual Geometry* asGeometry() { return this; } virtual const Geometry* asGeometry() const { return this; } bool empty() const; typedef std::vector< osg::ref_ptr > ArrayList; void setVertexArray(Array* array); Array* getVertexArray() { return _vertexArray.get(); } const Array* getVertexArray() const { return _vertexArray.get(); } void setNormalArray(Array* array) { setNormalArray(array, osg::Array::BIND_UNDEFINED); } void setNormalArray(Array* array, osg::Array::Binding binding); Array* getNormalArray() { return _normalArray.get(); } const Array* getNormalArray() const { return _normalArray.get(); } void setColorArray(Array* array) { setColorArray(array, osg::Array::BIND_UNDEFINED); } void setColorArray(Array* array, osg::Array::Binding binding); Array* getColorArray() { return _colorArray.get(); } const Array* getColorArray() const { return _colorArray.get(); } void setSecondaryColorArray(Array* array) { setSecondaryColorArray(array, osg::Array::BIND_UNDEFINED); } void setSecondaryColorArray(Array* array, osg::Array::Binding binding); Array* getSecondaryColorArray() { return _secondaryColorArray.get(); } const Array* getSecondaryColorArray() const { return _secondaryColorArray.get(); } void setFogCoordArray(Array* array) { setFogCoordArray(array, osg::Array::BIND_UNDEFINED); } void setFogCoordArray(Array* array, osg::Array::Binding binding); Array* getFogCoordArray() { return _fogCoordArray.get(); } const Array* getFogCoordArray() const { return _fogCoordArray.get(); } void setTexCoordArray(unsigned int unit, Array* array) { setTexCoordArray(unit, array, osg::Array::BIND_UNDEFINED); } void setTexCoordArray(unsigned int unit, Array* array, osg::Array::Binding binding); Array* getTexCoordArray(unsigned int unit); const Array* getTexCoordArray(unsigned int unit) const; unsigned int getNumTexCoordArrays() const { return static_cast(_texCoordList.size()); } void setTexCoordArrayList(const ArrayList& arrrayList); ArrayList& getTexCoordArrayList() { return _texCoordList; } const ArrayList& getTexCoordArrayList() const { return _texCoordList; } void setVertexAttribArray(unsigned int index, Array* array) { setVertexAttribArray(index, array, osg::Array::BIND_UNDEFINED); } void setVertexAttribArray(unsigned int index, Array* array, osg::Array::Binding binding); Array *getVertexAttribArray(unsigned int index); const Array *getVertexAttribArray(unsigned int index) const; unsigned int getNumVertexAttribArrays() const { return static_cast(_vertexAttribList.size()); } void setVertexAttribArrayList(const ArrayList& arrayList); ArrayList& getVertexAttribArrayList() { return _vertexAttribList; } const ArrayList& getVertexAttribArrayList() const { return _vertexAttribList; } typedef std::vector< ref_ptr > PrimitiveSetList; void setPrimitiveSetList(const PrimitiveSetList& primitives); PrimitiveSetList& getPrimitiveSetList() { return _primitives; } const PrimitiveSetList& getPrimitiveSetList() const { return _primitives; } unsigned int getNumPrimitiveSets() const { return static_cast(_primitives.size()); } PrimitiveSet* getPrimitiveSet(unsigned int pos) { return _primitives[pos].get(); } const PrimitiveSet* getPrimitiveSet(unsigned int pos) const { return _primitives[pos].get(); } /** Add a primitive set to the geometry. */ bool addPrimitiveSet(PrimitiveSet* primitiveset); /** Set a primitive set to the specified position in geometry's primitive set list. */ bool setPrimitiveSet(unsigned int i,PrimitiveSet* primitiveset); /** Insert a primitive set to the specified position in geometry's primitive set list. */ bool insertPrimitiveSet(unsigned int i,PrimitiveSet* primitiveset); /** Remove primitive set(s) from the specified position in geometry's primitive set list. */ bool removePrimitiveSet(unsigned int i,unsigned int numElementsToRemove=1); /** Get the index number of a primitive set, return a value between * 0 and getNumPrimitiveSet()-1 if found, if not found then return getNumPrimitiveSet(). * When checking for a valid find value use if ((value=geometry->getPrimitiveSetIndex(primitive))!=geometry.getNumPrimitiveSet()) */ unsigned int getPrimitiveSetIndex(const PrimitiveSet* primitiveset) const; /** Convinience method that checks all the vertex arrays to make sure that the buffer objects are all assigned appropriate.*/ void configureBufferObjects(); /** return true if any arrays are shared.*/ bool containsSharedArrays() const; /** duplicate any shared arrays.*/ void duplicateSharedArrays(); /** 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); /** Force a recompile on next draw() of any OpenGL objects associated with this geoset.*/ virtual void dirtyGLObjects(); /** 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; bool getArrayList(ArrayList& arrayList) const; typedef std::vector DrawElementsList; bool getDrawElementsList(DrawElementsList& drawElementsList) const; osg::VertexBufferObject* getOrCreateVertexBufferObject(); osg::ElementBufferObject* getOrCreateElementBufferObject(); /** 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; /** 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; /** Draw Geometry 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 Geometry for user-drawn objects. */ virtual void drawImplementation(RenderInfo& renderInfo) const; /** Set up the vertex arrays for the purpose of rendering, called by drawImplemtation() prior to it calling drawPrimitivesImplementation().*/ void drawVertexArraysImplementation(RenderInfo& renderInfo) const; /** dispatch the primitives to OpenGL, called by drawImplemtation() after calling drawVertexArraysImplementation().*/ void drawPrimitivesImplementation(RenderInfo& renderInfo) const; /** Return true, osg::Geometry does support accept(Drawable::AttributeFunctor&). */ virtual bool supports(const Drawable::AttributeFunctor&) const { return true; } /** Accept an Drawable::AttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */ virtual void accept(Drawable::AttributeFunctor& af); /** Return true, osg::Geometry does support accept(Drawable::ConstAttributeFunctor&). */ virtual bool supports(const Drawable::ConstAttributeFunctor&) const { return true; } /** Accept a Drawable::ConstAttributeFunctor and call its methods to tell it about the internal attributes that this Drawable has. */ virtual void accept(Drawable::ConstAttributeFunctor& af) const; /** Return true, osg::Geometry does support accept(PrimitiveFunctor&). */ virtual bool supports(const PrimitiveFunctor&) const { return true; } /** Accept a PrimitiveFunctor and call its methods to tell it about the internal primitives that this Drawable has. */ virtual void accept(PrimitiveFunctor& pf) const; /** Return true, osg::Geometry does support accept(PrimitiveIndexFunctor&). */ virtual bool supports(const PrimitiveIndexFunctor&) const { return true; } /** Accept a PrimitiveFunctor and call its methods to tell it about the internal primitives that this Drawable has. */ virtual void accept(PrimitiveIndexFunctor& pf) const; protected: Geometry& operator = (const Geometry&) { return *this;} virtual ~Geometry(); void addVertexBufferObjectIfRequired(osg::Array* array); void addElementBufferObjectIfRequired(osg::PrimitiveSet* primitiveSet); PrimitiveSetList _primitives; osg::ref_ptr _vertexArray; osg::ref_ptr _normalArray; osg::ref_ptr _colorArray; osg::ref_ptr _secondaryColorArray; osg::ref_ptr _fogCoordArray; ArrayList _texCoordList; ArrayList _vertexAttribList; bool _containsDeprecatedData; virtual VertexArrayState* createVertexArrayState(RenderInfo& renderInfo) const; public: /** Return true if the deprecated use array indices or BIND_PER_PRIMITIVE binding has been assigned to arrays.*/ bool containsDeprecatedData() const { return _containsDeprecatedData; } /** fallback for deprecated functionality. Return true if the Geometry contains any array indices or BIND_PER_PRIMITIVE arrays. */ bool checkForDeprecatedData(); /** fallback for deprecated functionality. Removes any array indices and BIND_PER_PRIMITIVE arrays.*/ void fixDeprecatedData(); #if defined(OSG_DEPRECATED_GEOMETRY_BINDING) /** deprecated, Same values as Array::Binding.*/ enum AttributeBinding { BIND_OFF=0, BIND_OVERALL=1, BIND_PER_PRIMITIVE_SET=2, BIND_PER_VERTEX=4 }; /** deprecated, use array->set*Binding(..). */ void setNormalBinding(AttributeBinding ab); void setColorBinding(AttributeBinding ab); void setSecondaryColorBinding(AttributeBinding ab); void setFogCoordBinding(AttributeBinding ab); void setVertexAttribBinding(unsigned int index,AttributeBinding ab); /** deprecated, use array->get*Binding(..). */ AttributeBinding getNormalBinding() const; AttributeBinding getColorBinding() const; AttributeBinding getSecondaryColorBinding() const; AttributeBinding getFogCoordBinding() const; AttributeBinding getVertexAttribBinding(unsigned int index) const; /** deprecated, use array->set*Normalize(..). */ void setVertexAttribNormalize(unsigned int index,GLboolean norm); /** deprecated, use array->get*Normalize(..). */ GLboolean getVertexAttribNormalize(unsigned int index) const; #endif }; /** Convinience visitor for making sure that any BufferObjects that might be required are set up in the scene graph.*/ class ConfigureBufferObjectsVisitor : public osg::NodeVisitor { public: ConfigureBufferObjectsVisitor(): osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) {} void apply(osg::Geometry& geometry) { geometry.configureBufferObjects(); } }; /** Convenience function to be used for creating quad geometry with texture coords. * Tex coords go from left bottom (l,b) to right top (r,t). */ extern OSG_EXPORT Geometry* createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVec,const Vec3& heightVec, float l, float b, float r, float t); /** Convenience function to be used for creating quad geometry with texture coords. * Tex coords go from bottom left (0,0) to top right (s,t). */ inline Geometry* createTexturedQuadGeometry(const Vec3& corner,const Vec3& widthVec,const Vec3& heightVec, float s=1.0f, float t=1.0f) { return createTexturedQuadGeometry(corner,widthVec,heightVec, 0.0f, 0.0f, s, t); } } // namespace osg #endif