# Visualization Library

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

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

- Main Page
- 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.com                                               */
    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 <vlCore/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   public:
    00057     GLuint primitiveRestartIndex() const { return mPrimitiveRestartIndex; }
    00058
    00061     void setPrimitiveRestartIndex(GLuint index) { mPrimitiveRestartIndex = index; }
    00062
    00064     bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
    00065
    00067     void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
    00068
    00071     void setCountVector(const std::vector<GLsizei>& vcount)
    00072     {
    00073       mCountVector = vcount;
    00074       compute_pointer_vector();
    00075     }
    00076
    00078     const std::vector<GLsizei>& countVector() const { return mCountVector; }
    00079
    00083     void setBaseVertices(const std::vector<GLint>& base_verts) { mBaseVertices = base_verts; }
    00084
    00086     const std::vector<GLint>& baseVertices() const { return mBaseVertices; }
    00087
    00089     std::vector<GLint>& baseVertices() { return mBaseVertices; }
    00090
    00091   protected:
    00092     virtual void compute_pointer_vector() = 0;
    00093
    00094   protected:
    00095     GLuint mPrimitiveRestartIndex;
    00096     bool mPrimitiveRestartEnabled;
    00097     std::vector<GLsizei> mCountVector;
    00098     std::vector<GLint>   mBaseVertices;
    00099   };
    00100   //------------------------------------------------------------------------------
    00101   // MultiDrawElements
    00102   //------------------------------------------------------------------------------
    00122   template <GLenum Tgltype, class arr_type>
    00123   class MultiDrawElements: public MultiDrawElementsBase
    00124   {
    00125   public:
    00126     virtual const char* className() { return "vl::MultiDrawElements"; }
    00127
    00128     MultiDrawElements(EPrimitiveType primitive = PT_TRIANGLES)
    00129     {
    00130       VL_DEBUG_SET_OBJECT_NAME()
    00131       mType                    = primitive;
    00132       mIndexBuffer             = new arr_type;
    00133       mPrimitiveRestartIndex   = typename arr_type::scalar_type(~0);
    00134       mPrimitiveRestartEnabled = false;
    00135     }
    00136
    00137     MultiDrawElements& operator=(const MultiDrawElements& other)
    00138     {
    00139       DrawCall::operator=(other);
    00140       *indices() = *other.indices();
    00141       mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
    00142       mPrimitiveRestartIndex   = other.mPrimitiveRestartIndex;
    00143       setCountVector(other.mCountVector);
    00144       return *this;
    00145     }
    00146
    00147     virtual ref<DrawCall> clone() const
    00148     {
    00149       ref<MultiDrawElements> de = new MultiDrawElements;
    00150       *de = *this;
    00151       return de;
    00152     }
    00153
    00154     virtual unsigned int handle() const { return indices()->gpuBuffer()->handle(); }
    00155
    00156     arr_type* indices() { return mIndexBuffer.get(); }
    00157
    00158     const arr_type* indices() const { return mIndexBuffer.get(); }
    00159
    00160     virtual void updateVBOs(bool discard_local_data=false, bool force_update=false)
    00161     {
    00162       if (indices()->isVBODirty() || force_update)
    00163         indices()->updateVBO(discard_local_data);
    00164     }
    00165
    00166     virtual void deleteVBOs()
    00167     {
    00168       indices()->gpuBuffer()->deleteGLBufferObject();
    00169     }
    00170
    00171     virtual void clearLocalBuffer()
    00172     {
    00173       indices()->gpuBuffer()->resize(0);
    00174     }
    00175
    00176     virtual void render(bool use_vbo) const
    00177     {
    00178       VL_CHECK(GLEW_VERSION_1_4);
    00179       VL_CHECK(!use_vbo || (use_vbo && (GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0)))
    00180       use_vbo &= GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0; // && indices()->gpuBuffer()->handle() && indices()->sizeGPU();
    00181       if ( !use_vbo && !indices()->size() )
    00182         return;
    00183
    00184       // apply patch parameters if any and if using PT_PATCHES
    00185       applyPatchParameters();
    00186
    00187       // primitive restart enable
    00188       if(primitiveRestartEnabled())
    00189       {
    00190         if(GLEW_VERSION_3_1)
    00191         {
    00192           glEnable(GL_PRIMITIVE_RESTART);
    00193           glPrimitiveRestartIndex(primitiveRestartIndex());
    00194         }
    00195         else
    00196         if(GLEW_NV_primitive_restart)
    00197         {
    00198           glEnable(GL_PRIMITIVE_RESTART_NV);
    00199           glPrimitiveRestartIndexNV(primitiveRestartIndex());
    00200         }
    00201         else
    00202         {
    00203           vl::Log::error("MultiDrawElements error: primitive restart not supported by this OpenGL implementation!\n");
    00204           VL_TRAP();
    00205           return;
    00206         }
    00207       }
    00208
    00209       GLvoid **indices_ptr = (GLvoid**)&mPointerVector[0];
    00210       if (use_vbo && indices()->gpuBuffer()->handle())
    00211       {
    00212         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices()->gpuBuffer()->handle());
    00213         indices_ptr = (GLvoid**)&mNULLPointerVector[0];
    00214       }
    00215       else
    00216         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    00217
    00218       if (baseVertices().size())
    00219       {
    00220         VL_CHECK( baseVertices().size() == pointerVector().size() )
    00221         VL_CHECK( baseVertices().size() == countVector().size() )
    00222         if (GLEW_ARB_draw_elements_base_vertex || GLEW_VERSION_3_1)
    00223           glMultiDrawElementsBaseVertex(
    00224             primitiveType(), (GLsizei*)&mCountVector[0], indices()->glType(), indices_ptr, (GLsizei)mCountVector.size(), (GLint*)&mBaseVertices[0]
    00225           );
    00226         else
    00227         {
    00228           vl::Log::error("MultiDrawElements::render(): glMultiDrawElementsBaseVertex() not supported!\n"
    00229             "OpenGL 3.1 or GL_ARB_draw_elements_base_vertex extension required.\n"
    00230           );
    00231         }
    00232       }
    00233       else
    00234         glMultiDrawElements( primitiveType(), (GLsizei*)&mCountVector[0], indices()->glType(), (const GLvoid**)indices_ptr, (GLsizei)mCountVector.size() );
    00235
    00236       // primitive restart disable
    00237       if(primitiveRestartEnabled())
    00238       {
    00239         if(GLEW_VERSION_3_1)
    00240           glDisable(GL_PRIMITIVE_RESTART);
    00241         else
    00242         if(GLEW_NV_primitive_restart)
    00243           glDisable(GL_PRIMITIVE_RESTART_NV);
    00244       }
    00245     }
    00246
    00247     TriangleIterator triangleIterator() const;
    00248
    00249     IndexIterator indexIterator() const
    00250     {
    00251       ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
    00252       iie->initialize( mIndexBuffer.get(), &mBaseVertices, &mCountVector, 0, mPrimitiveRestartEnabled, mPrimitiveRestartIndex );
    00253       IndexIterator iit;
    00254       iit.initialize( iie.get() );
    00255       return iit;
    00256     }
    00257
    00259     const std::vector<const typename arr_type::scalar_type*>& pointerVector() const { return mPointerVector; }
    00260
    00261   protected:
    00262     void compute_pointer_vector()
    00263     {
    00264       // set all to null: used when VBO is active.
    00265       mNULLPointerVector.resize( mCountVector.size() );
    00266
    00267       // used when VBOs are not active.
    00268       mPointerVector.clear();
    00269       const typename arr_type::scalar_type* ptr = (const typename arr_type::scalar_type*)indices()->gpuBuffer()->ptr();
    00270       for(size_t i=0; i<mCountVector.size(); ++i)
    00271       {
    00272         mPointerVector.push_back(ptr);
    00273         ptr += mCountVector[i];
    00274       }
    00275       VL_CHECK( ptr - (const typename arr_type::scalar_type*)indices()->gpuBuffer()->ptr() <= (int)indices()->size() );
    00276     }
    00277
    00278
    00279   protected:
    00280     ref< arr_type > mIndexBuffer;
    00281     std::vector<const typename arr_type::scalar_type*> mPointerVector;
    00282     std::vector<const typename arr_type::scalar_type*> mNULLPointerVector;
    00283   };
    00284   //------------------------------------------------------------------------------
    00285   // typedefs
    00286   //------------------------------------------------------------------------------
    00288   class MultiDrawElementsUInt: public MultiDrawElements<GL_UNSIGNED_INT, ArrayUInt1>
    00289   {
    00290   public:
    00291     MultiDrawElementsUInt(EPrimitiveType primitive = PT_TRIANGLES)
    00292     :MultiDrawElements<GL_UNSIGNED_INT, ArrayUInt1>(primitive) {}
    00293   };
    00294   //------------------------------------------------------------------------------
    00296   class MultiDrawElementsUShort: public MultiDrawElements<GL_UNSIGNED_SHORT, ArrayUShort1>
    00297   {
    00298   public:
    00299     MultiDrawElementsUShort(EPrimitiveType primitive = PT_TRIANGLES)
    00300     :MultiDrawElements<GL_UNSIGNED_SHORT, ArrayUShort1>(primitive) {}
    00301   };
    00302   //------------------------------------------------------------------------------
    00304   class MultiDrawElementsUByte: public MultiDrawElements<GL_UNSIGNED_BYTE, ArrayUByte1>
    00305   {
    00306   public:
    00307     MultiDrawElementsUByte(EPrimitiveType primitive = PT_TRIANGLES)
    00308     :MultiDrawElements<GL_UNSIGNED_BYTE, ArrayUByte1>(primitive) {}
    00309   };
    00310 //-----------------------------------------------------------------------------
    00311   template <GLenum Tgltype, class arr_type>
    00312   TriangleIterator MultiDrawElements<Tgltype, arr_type>::triangleIterator() const
    00313   {
    00314     ref< TriangleIteratorMulti<arr_type> > it =
    00315       new TriangleIteratorMulti<arr_type>( &mBaseVertices, &mCountVector, mIndexBuffer.get(), primitiveType(),
    00316           primitiveRestartEnabled(), primitiveRestartIndex() );
    00317     it->initialize();
    00318     return TriangleIterator(it.get());
    00319   }
    00320 //-----------------------------------------------------------------------------
    00321 }
    00322
    00323 #endif

Visualization Library v2011.05.1142 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 26 2011 22:51:24.
Permission is granted to use this page to write and publish articles regarding Visualization Library.