# Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics

[Home] [Tutorials] [All Classes] [Grouped Classes]

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

# D:/VL/BuildSystem/VL_DISTRO/Visualization_Library_SDK/src/vlGraphics/MultiDrawElements.hpp

Go to the documentation of this file.

    00001 /**************************************************************************************/
    00002 /*                                                                                    */
    00003 /*  Visualization Library                                                             */
    00004 /*  http://www.visualizationlibrary.org                                               */
    00005 /*                                                                                    */
    00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
    00007 /*  All rights reserved.                                                              */
    00008 /*                                                                                    */
    00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
    00010 /*  are permitted provided that the following conditions are met:                     */
    00011 /*                                                                                    */
    00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
    00013 /*  list of conditions and the following disclaimer.                                  */
    00014 /*                                                                                    */
    00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
    00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
    00017 /*  other materials provided with the distribution.                                   */
    00018 /*                                                                                    */
    00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
    00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
    00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
    00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
    00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
    00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
    00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
    00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
    00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
    00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
    00029 /*                                                                                    */
    00030 /**************************************************************************************/
    00031
    00032 #ifndef MultiDrawElements_INCLUDE_ONCE
    00033 #define MultiDrawElements_INCLUDE_ONCE
    00034
    00035 #include <vlGraphics/DrawCall.hpp>
    00036 #include <vlGraphics/Array.hpp>
    00037 #include <vlGraphics/TriangleIterator.hpp>
    00038 #include <vlCore/Log.hpp>
    00039 #include <vlCore/Say.hpp>
    00040 #include <algorithm>
    00041
    00042 namespace vl
    00043 {
    00044   //------------------------------------------------------------------------------
    00045   // MultiDrawElementsBase
    00046   //------------------------------------------------------------------------------
    00052   class MultiDrawElementsBase: public DrawCall
    00053   {
    00054     VL_INSTRUMENT_ABSTRACT_CLASS(vl::MultiDrawElementsBase, DrawCall)
    00055
    00056   public:
    00058     virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
    00059
    00061     void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
    00062
    00065     void finalizeSetup()
    00066     {
    00067       // update pointers
    00068       computePointerVector();
    00069       computeBufferObjectPointerVector();
    00070       // set default base vertices to 0
    00071       if (mBaseVertices.size() != mCountVector.size())
    00072         mBaseVertices.resize(mCountVector.size());
    00073     }
    00074
    00077     void setCountVector(const std::vector<GLsizei>& vcount)
    00078     {
    00079       mCountVector = vcount;
    00080       finalizeSetup();
    00081     }
    00082
    00085     void setCountVector(const GLsizei* vcount, size_t size)
    00086     {
    00087       mCountVector.resize(size);
    00088       for(size_t i=0; i<size; ++i)
    00089         mCountVector[i] = vcount[i];
    00090       finalizeSetup();
    00091     }
    00092
    00094     const std::vector<GLsizei>& countVector() const { return mCountVector; }
    00095
    00097     std::vector<GLsizei>& countVector() { return mCountVector; }
    00098
    00102     void setBaseVertices(const std::vector<GLint>& base_verts) { mBaseVertices = base_verts; }
    00103
    00105     const std::vector<GLint>& baseVertices() const { return mBaseVertices; }
    00106
    00108     std::vector<GLint>& baseVertices() { return mBaseVertices; }
    00109
    00112     virtual void computePointerVector() = 0;
    00113
    00116     virtual void computeBufferObjectPointerVector() = 0;
    00117
    00118   protected:
    00119     bool mPrimitiveRestartEnabled;
    00120     std::vector<GLsizei> mCountVector;
    00121     std::vector<GLint>   mBaseVertices;
    00122   };
    00123   //------------------------------------------------------------------------------
    00124   // MultiDrawElements
    00125   //------------------------------------------------------------------------------
    00150   template <class arr_type>
    00151   class MultiDrawElements: public MultiDrawElementsBase
    00152   {
    00153     VL_INSTRUMENT_CLASS(vl::MultiDrawElements<arr_type>, MultiDrawElementsBase)
    00154
    00155   public:
    00156     typedef typename arr_type::scalar_type index_type;
    00158     static const index_type primitive_restart_index = index_type(~0);
    00159     virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
    00160
    00161   public:
    00162     MultiDrawElements(EPrimitiveType primitive = PT_TRIANGLES)
    00163     {
    00164       VL_DEBUG_SET_OBJECT_NAME()
    00165       mType                    = primitive;
    00166       mIndexBuffer             = new arr_type;
    00167       mPrimitiveRestartEnabled = false;
    00168     }
    00169
    00170     MultiDrawElements& operator=(const MultiDrawElements& other)
    00171     {
    00172       super::operator=(other);
    00173       *indexBuffer() = *other.indexBuffer();
    00174       mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
    00175       setCountVector(other.mCountVector);
    00176       return *this;
    00177     }
    00178
    00179     virtual ref<DrawCall> clone() const
    00180     {
    00181       ref<MultiDrawElements> de = new MultiDrawElements;
    00182       *de = *this;
    00183       return de;
    00184     }
    00185
    00186     void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
    00187
    00188     arr_type* indexBuffer() { return mIndexBuffer.get(); }
    00189
    00190     const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
    00191
    00192     virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
    00193     {
    00194       if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
    00195         indexBuffer()->updateBufferObject(mode);
    00196     }
    00197
    00198     virtual void deleteBufferObject()
    00199     {
    00200       indexBuffer()->bufferObject()->deleteBufferObject();
    00201     }
    00202
    00203     virtual void render(bool use_bo) const
    00204     {
    00205       VL_CHECK_OGL()
    00206       VL_CHECK(Has_GL_EXT_multi_draw_arrays||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0);
    00207       VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
    00208       use_bo &= Has_BufferObject; // && indexBuffer()->bufferObject()->handle() && indexBuffer()->sizeBufferObject();
    00209       if ( !use_bo && !indexBuffer()->size() )
    00210         return;
    00211
    00212       // apply patch parameters if any and if using PT_PATCHES
    00213       applyPatchParameters();
    00214
    00215       // primitive restart enable
    00216       if(primitiveRestartEnabled())
    00217       {
    00218         VL_CHECK(Has_Primitive_Restart);
    00219         glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
    00220         glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
    00221       }
    00222
    00223       const GLvoid **indices_ptr = NULL;
    00224       if (use_bo && indexBuffer()->bufferObject()->handle())
    00225       {
    00226         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
    00227         VL_CHECK(!mBufferObjectPointerVector.empty())
    00228         indices_ptr = (const GLvoid**)&mBufferObjectPointerVector[0];
    00229       }
    00230       else
    00231       {
    00232         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    00233         VL_CHECK(!mPointerVector.empty())
    00234         indices_ptr = (const GLvoid**)&mPointerVector[0];
    00235       }
    00236
    00237       if (baseVertices().size())
    00238       {
    00239         VL_CHECK( baseVertices().size() == pointerVector().size() )
    00240         VL_CHECK( baseVertices().size() == countVector().size() )
    00241         if (Has_GL_ARB_draw_elements_base_vertex||Has_GL_Version_3_1||Has_GL_Version_4_0)
    00242         {
    00243           glMultiDrawElementsBaseVertex( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), indices_ptr, (GLsizei)mCountVector.size(), (GLint*)&mBaseVertices[0] ); VL_CHECK_OGL()
    00244         }
    00245         else
    00246         {
    00247           vl::Log::error("MultiDrawElements::render(): glMultiDrawElementsBaseVertex() not supported!\n"
    00248             "OpenGL 3.1 or GL_ARB_draw_elements_base_vertex extension required.\n"
    00249           );
    00250         }
    00251       }
    00252       else
    00253       {
    00254         glMultiDrawElements( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), (const GLvoid**)indices_ptr, (GLsizei)mCountVector.size() ); VL_CHECK_OGL()
    00255       }
    00256
    00257       // primitive restart disable
    00258       if(primitiveRestartEnabled())
    00259       {
    00260         glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
    00261       }
    00262     }
    00263
    00264     TriangleIterator triangleIterator() const;
    00265
    00266     IndexIterator indexIterator() const
    00267     {
    00268       ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
    00269       iie->initialize( mIndexBuffer.get(), &mBaseVertices, &mCountVector, 0, mPrimitiveRestartEnabled, primitive_restart_index );
    00270       IndexIterator iit;
    00271       iit.initialize( iie.get() );
    00272       return iit;
    00273     }
    00274
    00277     const std::vector<const index_type*>& pointerVector() const { return mPointerVector; }
    00278
    00280     std::vector<const index_type*>& pointerVector() { return mPointerVector; }
    00281
    00283     const std::vector<const index_type*>& bufferObjectPointerVector() const { return mBufferObjectPointerVector; }
    00284
    00286     std::vector<const index_type*>& bufferObjectPointerVector() { return mBufferObjectPointerVector; }
    00287
    00289     void computePointerVector()
    00290     {
    00291       VL_CHECK( indexBuffer() && indexBuffer()->size() )
    00292       mPointerVector.resize( mCountVector.size() );
    00293       const index_type* ptr = (const index_type*)indexBuffer()->bufferObject()->ptr();
    00294       for(size_t i=0; i<mCountVector.size(); ++i)
    00295       {
    00296         mPointerVector[i] = ptr;
    00297         ptr += mCountVector[i];
    00298       }
    00299     }
    00300
    00302     void computeBufferObjectPointerVector()
    00303     {
    00304       VL_CHECK( indexBuffer() && indexBuffer()->size() )
    00305       mBufferObjectPointerVector.resize( mPointerVector.size() );
    00306       const index_type* base_ptr = (const index_type*)indexBuffer()->ptr();
    00307       VL_CHECK(base_ptr)
    00308       for(size_t i=0; i<mPointerVector.size(); ++i)
    00309       {
    00310         size_t offset = mPointerVector[i] - base_ptr;
    00311         mBufferObjectPointerVector[i] = (const index_type*)0 + offset;
    00312       }
    00313     }
    00314
    00315   protected:
    00316     ref< arr_type > mIndexBuffer;
    00317     std::vector<const index_type*> mPointerVector;
    00318     std::vector<const index_type*> mBufferObjectPointerVector;
    00319   };
    00320   //------------------------------------------------------------------------------
    00321   // typedefs
    00322   //------------------------------------------------------------------------------
    00324   class MultiDrawElementsUInt: public MultiDrawElements<ArrayUInt1>
    00325   {
    00326     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUInt, MultiDrawElements< ArrayUInt1>)
    00327
    00328   public:
    00329     MultiDrawElementsUInt(EPrimitiveType primitive = PT_TRIANGLES)
    00330     :MultiDrawElements<ArrayUInt1>(primitive)
    00331     {
    00332       VL_DEBUG_SET_OBJECT_NAME();
    00333     }
    00334   };
    00335   //------------------------------------------------------------------------------
    00337   class MultiDrawElementsUShort: public MultiDrawElements<ArrayUShort1>
    00338   {
    00339     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUShort, MultiDrawElements< ArrayUShort1>)
    00340
    00341   public:
    00342     MultiDrawElementsUShort(EPrimitiveType primitive = PT_TRIANGLES)
    00343     :MultiDrawElements<ArrayUShort1>(primitive)
    00344     {
    00345       VL_DEBUG_SET_OBJECT_NAME();
    00346     }
    00347   };
    00348   //------------------------------------------------------------------------------
    00350   class MultiDrawElementsUByte: public MultiDrawElements<ArrayUByte1>
    00351   {
    00352     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUByte, MultiDrawElements<ArrayUByte1>)
    00353
    00354   public:
    00355     MultiDrawElementsUByte(EPrimitiveType primitive = PT_TRIANGLES)
    00356     :MultiDrawElements<ArrayUByte1>(primitive)
    00357     {
    00358       VL_DEBUG_SET_OBJECT_NAME();
    00359     }
    00360   };
    00361 //-----------------------------------------------------------------------------
    00362   template <class arr_type>
    00363   TriangleIterator MultiDrawElements<arr_type>::triangleIterator() const
    00364   {
    00365     ref< TriangleIteratorMulti<arr_type> > it =
    00366       new TriangleIteratorMulti<arr_type>( &mBaseVertices, &mCountVector, mIndexBuffer.get(), primitiveType(),
    00367           primitiveRestartEnabled(), primitive_restart_index );
    00368     it->initialize();
    00369     return TriangleIterator(it.get());
    00370   }
    00371 //-----------------------------------------------------------------------------
    00372 }
    00373
    00374 #endif

Visualization Library v2011.09.1162 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu Jan 26 2012 00:43:39.
Permission is granted to use this page to write and publish articles regarding Visualization Library.