Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/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 <vlGraphics/LineIterator.hpp>
00039 #include <vlCore/Log.hpp>
00040 #include <vlCore/Say.hpp>
00041 #include <algorithm>
00042 
00043 namespace vl
00044 {
00045   //------------------------------------------------------------------------------
00046   // MultiDrawElementsBase
00047   //------------------------------------------------------------------------------
00053   class MultiDrawElementsBase: public DrawCall
00054   {
00055     VL_INSTRUMENT_ABSTRACT_CLASS(vl::MultiDrawElementsBase, DrawCall)
00056 
00057   public:
00059     virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
00060     
00062     void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
00063 
00066     void finalizeSetup()
00067     {
00068       // update pointers
00069       computePointerVector();
00070       computeBufferObjectPointerVector();
00071       // set default base vertices to 0
00072       if (mBaseVertices.size() != mCountVector.size())
00073         mBaseVertices.resize(mCountVector.size());
00074     }
00075 
00078     void setCountVector(const std::vector<GLsizei>& vcount)
00079     {
00080       mCountVector = vcount;
00081       finalizeSetup();
00082     }
00083 
00086     void setCountVector(const GLsizei* vcount, size_t size)
00087     {
00088       mCountVector.resize(size);
00089       for(size_t i=0; i<size; ++i)
00090         mCountVector[i] = vcount[i];
00091       finalizeSetup();
00092     }
00093 
00095     const std::vector<GLsizei>& countVector() const { return mCountVector; }
00096 
00098     std::vector<GLsizei>& countVector() { return mCountVector; }
00099 
00103     void setBaseVertices(const std::vector<GLint>& base_verts) { mBaseVertices = base_verts; }
00104 
00106     const std::vector<GLint>& baseVertices() const { return mBaseVertices; }
00107 
00109     std::vector<GLint>& baseVertices() { return mBaseVertices; }
00110 
00113     virtual void computePointerVector() = 0;
00114 
00117     virtual void computeBufferObjectPointerVector() = 0;
00118 
00119   protected:
00120     bool mPrimitiveRestartEnabled;
00121     std::vector<GLsizei> mCountVector;
00122     std::vector<GLint>   mBaseVertices;
00123   };
00124   //------------------------------------------------------------------------------
00125   // MultiDrawElements
00126   //------------------------------------------------------------------------------
00151   template <class arr_type>
00152   class MultiDrawElements: public MultiDrawElementsBase
00153   {
00154     VL_INSTRUMENT_CLASS(vl::MultiDrawElements<arr_type>, MultiDrawElementsBase)
00155 
00156   public:
00157     typedef typename arr_type::scalar_type index_type;
00159     static const index_type primitive_restart_index = index_type(~0);
00160     virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
00161 
00162   public:
00163     MultiDrawElements(EPrimitiveType primitive = PT_TRIANGLES)
00164     {
00165       VL_DEBUG_SET_OBJECT_NAME()
00166       mType                    = primitive;
00167       mIndexBuffer             = new arr_type;
00168       mPrimitiveRestartEnabled = false;
00169     }
00170 
00171     MultiDrawElements& operator=(const MultiDrawElements& other)
00172     {
00173       super::operator=(other);
00174       *indexBuffer() = *other.indexBuffer();
00175       mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
00176       setCountVector(other.mCountVector);
00177       return *this;
00178     }
00179 
00180     virtual ref<DrawCall> clone() const 
00181     { 
00182       ref<MultiDrawElements> de = new MultiDrawElements;
00183       *de = *this;
00184       return de;
00185     }
00186 
00187     void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
00188 
00189     arr_type* indexBuffer() { return mIndexBuffer.get(); }
00190 
00191     const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
00192 
00193     virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
00194     {
00195       if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
00196         indexBuffer()->updateBufferObject(mode);
00197     }
00198 
00199     virtual void deleteBufferObject()
00200     {
00201       indexBuffer()->bufferObject()->deleteBufferObject();
00202     }
00203 
00204     virtual void render(bool use_bo) const
00205     {
00206       VL_CHECK_OGL()
00207       VL_CHECK(Has_GL_EXT_multi_draw_arrays||Has_GL_Version_1_4||Has_GL_Version_3_0||Has_GL_Version_4_0);
00208       VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
00209       use_bo &= Has_BufferObject; // && indexBuffer()->bufferObject()->handle() && indexBuffer()->sizeBufferObject();
00210       if ( !use_bo && !indexBuffer()->size() )
00211         return;
00212 
00213       // apply patch parameters if any and if using PT_PATCHES
00214       applyPatchParameters();
00215 
00216       // primitive restart enable
00217       if(primitiveRestartEnabled())
00218       {
00219         VL_CHECK(Has_Primitive_Restart);
00220         glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
00221         glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
00222       }
00223 
00224       const GLvoid **indices_ptr = NULL;
00225       if (use_bo && indexBuffer()->bufferObject()->handle())
00226       {
00227         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
00228         VL_CHECK(!mBufferObjectPointerVector.empty())
00229         indices_ptr = (const GLvoid**)&mBufferObjectPointerVector[0];
00230       }
00231       else
00232       {
00233         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
00234         VL_CHECK(!mPointerVector.empty())
00235         indices_ptr = (const GLvoid**)&mPointerVector[0];
00236       }
00237 
00238       if (baseVertices().size())
00239       {
00240         VL_CHECK( baseVertices().size() == pointerVector().size() )
00241         VL_CHECK( baseVertices().size() == countVector().size() )
00242         if (Has_GL_ARB_draw_elements_base_vertex||Has_GL_Version_3_1||Has_GL_Version_4_0)
00243         {
00244           glMultiDrawElementsBaseVertex( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), indices_ptr, (GLsizei)mCountVector.size(), (GLint*)&mBaseVertices[0] ); VL_CHECK_OGL()
00245         }
00246         else
00247         {
00248           vl::Log::error("MultiDrawElements::render(): glMultiDrawElementsBaseVertex() not supported!\n"
00249             "OpenGL 3.1 or GL_ARB_draw_elements_base_vertex extension required.\n"
00250           );
00251         }
00252       }
00253       else
00254       {
00255         glMultiDrawElements( primitiveType(), (GLsizei*)&mCountVector[0], indexBuffer()->glType(), (const GLvoid**)indices_ptr, (GLsizei)mCountVector.size() ); VL_CHECK_OGL()
00256       }
00257 
00258       // primitive restart disable
00259       if(primitiveRestartEnabled())
00260       {
00261         glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
00262       }
00263     }
00264 
00265     TriangleIterator triangleIterator() const;
00266 
00267     LineIterator lineIterator() const;
00268 
00269     IndexIterator indexIterator() const
00270     {
00271       ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
00272       iie->initialize( mIndexBuffer.get(), &mBaseVertices, &mCountVector, 0, mPrimitiveRestartEnabled, primitive_restart_index );
00273       IndexIterator iit;
00274       iit.initialize( iie.get() );
00275       return iit;
00276     }
00277 
00280     const std::vector<const index_type*>& pointerVector() const { return mPointerVector; }
00281 
00283     std::vector<const index_type*>& pointerVector() { return mPointerVector; }
00284 
00286     const std::vector<const index_type*>& bufferObjectPointerVector() const { return mBufferObjectPointerVector; }
00287 
00289     std::vector<const index_type*>& bufferObjectPointerVector() { return mBufferObjectPointerVector; }
00290 
00292     void computePointerVector()
00293     {
00294       VL_CHECK( indexBuffer() && indexBuffer()->size() )
00295       mPointerVector.resize( mCountVector.size() );
00296       const index_type* ptr = (const index_type*)indexBuffer()->bufferObject()->ptr();
00297       for(size_t i=0; i<mCountVector.size(); ++i)
00298       {
00299         mPointerVector[i] = ptr;
00300         ptr += mCountVector[i];
00301       }
00302     }
00303 
00305     void computeBufferObjectPointerVector()
00306     {
00307       VL_CHECK( indexBuffer() && indexBuffer()->size() )
00308       mBufferObjectPointerVector.resize( mPointerVector.size() );
00309       const index_type* base_ptr = (const index_type*)indexBuffer()->ptr();
00310       VL_CHECK(base_ptr)
00311       for(size_t i=0; i<mPointerVector.size(); ++i)
00312       {
00313         size_t offset = mPointerVector[i] - base_ptr;
00314         mBufferObjectPointerVector[i] = (const index_type*)0 + offset;
00315       }
00316     }
00317 
00318   protected:
00319     ref< arr_type > mIndexBuffer;
00320     std::vector<const index_type*> mPointerVector;
00321     std::vector<const index_type*> mBufferObjectPointerVector;
00322   };
00323   //------------------------------------------------------------------------------
00324   // typedefs
00325   //------------------------------------------------------------------------------
00327   class MultiDrawElementsUInt: public MultiDrawElements<ArrayUInt1>
00328   {
00329     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUInt, MultiDrawElements< ArrayUInt1>)
00330 
00331   public:
00332     MultiDrawElementsUInt(EPrimitiveType primitive = PT_TRIANGLES)
00333     :MultiDrawElements<ArrayUInt1>(primitive)
00334     {
00335       VL_DEBUG_SET_OBJECT_NAME();
00336     }
00337   };
00338   //------------------------------------------------------------------------------
00340   class MultiDrawElementsUShort: public MultiDrawElements<ArrayUShort1>
00341   {
00342     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUShort, MultiDrawElements< ArrayUShort1>)
00343 
00344   public:
00345     MultiDrawElementsUShort(EPrimitiveType primitive = PT_TRIANGLES)
00346     :MultiDrawElements<ArrayUShort1>(primitive)
00347     {
00348       VL_DEBUG_SET_OBJECT_NAME();
00349     }
00350   };
00351   //------------------------------------------------------------------------------
00353   class MultiDrawElementsUByte: public MultiDrawElements<ArrayUByte1>
00354   {
00355     VL_INSTRUMENT_CLASS(vl::MultiDrawElementsUByte, MultiDrawElements<ArrayUByte1>)
00356 
00357   public:
00358     MultiDrawElementsUByte(EPrimitiveType primitive = PT_TRIANGLES)
00359     :MultiDrawElements<ArrayUByte1>(primitive)
00360     {
00361       VL_DEBUG_SET_OBJECT_NAME();
00362     }
00363   };
00364 //-----------------------------------------------------------------------------
00365   template <class arr_type>
00366   TriangleIterator MultiDrawElements<arr_type>::triangleIterator() const
00367   {
00368     ref< TriangleIteratorMulti<arr_type> > it = 
00369       new TriangleIteratorMulti<arr_type>( &mBaseVertices, &mCountVector, mIndexBuffer.get(), primitiveType(), 
00370           primitiveRestartEnabled(), primitive_restart_index );
00371     it->initialize();
00372     return TriangleIterator(it.get());
00373   }
00374 //-----------------------------------------------------------------------------
00375   template <class arr_type>
00376   LineIterator MultiDrawElements<arr_type>::lineIterator() const
00377   {
00378       ref< LineIteratorMulti<arr_type> > it =
00379         new LineIteratorMulti<arr_type>( &mBaseVertices, &mCountVector, mIndexBuffer.get(), primitiveType(),
00380             primitiveRestartEnabled(), primitive_restart_index );
00381       it->initialize();
00382       return LineIterator(it.get());
00383   }
00384 //-----------------------------------------------------------------------------
00385 }
00386 
00387 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:38.
Permission is granted to use this page to write and publish articles regarding Visualization Library.