# 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/DrawElements.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 DrawElements_INCLUDE_ONCE
    00033 #define DrawElements_INCLUDE_ONCE
    00034
    00035 #include <vlGraphics/DrawCall.hpp>
    00036 #include <vlGraphics/TriangleIterator.hpp>
    00037 #include <vlCore/Array.hpp>
    00038 #include <vlCore/Log.hpp>
    00039 #include <vlCore/Say.hpp>
    00040 #include <algorithm>
    00041
    00042 namespace vl
    00043 {
    00044
    00045   //------------------------------------------------------------------------------
    00046   // DrawElementsBase
    00047   //------------------------------------------------------------------------------
    00053   class DrawElementsBase: public DrawCall
    00054   {
    00055   public:
    00058     GLuint primitiveRestartIndex() const { return mPrimitiveRestartIndex; }
    00059
    00062     void setPrimitiveRestartIndex(GLuint index) { mPrimitiveRestartIndex = index; }
    00063
    00065     bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
    00066
    00068     void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
    00069
    00071     void setInstances(int instances) { mInstances = instances; }
    00072
    00074     int instances() const { return mInstances; }
    00075
    00080     void setBaseVertex(int base_vertex) { mBaseVertex = base_vertex; }
    00081
    00084     int  baseVertex() const { return mBaseVertex; }
    00085
    00086   protected:
    00087     int mInstances;
    00088     GLuint mPrimitiveRestartIndex;
    00089     bool mPrimitiveRestartEnabled;
    00090     int  mBaseVertex;
    00091   };
    00092   //------------------------------------------------------------------------------
    00093   // DrawElements
    00094   //------------------------------------------------------------------------------
    00117   template <GLenum Tgltype, class arr_type>
    00118   class DrawElements: public DrawElementsBase
    00119   {
    00120   private:
    00121     template<typename T>
    00122     class Triangle
    00123     {
    00124     public:
    00125       T ABC[3];
    00126       bool operator<(const Triangle< typename arr_type::scalar_type>& b) const
    00127       {
    00128         if (ABC[0] != b.ABC[0])
    00129           return ABC[0] < b.ABC[0];
    00130         else
    00131         if (ABC[1] != b.ABC[1])
    00132           return ABC[1] < b.ABC[1];
    00133         else
    00134           return ABC[2] < b.ABC[2];
    00135       }
    00136       void rotate()
    00137       {
    00138         if (ABC[0] > ABC[1])
    00139           { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
    00140         if (ABC[0] > ABC[1])
    00141           { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
    00142       }
    00143     };
    00144
    00145   public:
    00146     virtual const char* className() { return "vl::DrawElements"; }
    00147
    00148     DrawElements(EPrimitiveType primitive = PT_TRIANGLES, int instances = 1)
    00149     {
    00150       VL_DEBUG_SET_OBJECT_NAME()
    00151       mType                    = primitive;
    00152       mInstances               = instances;
    00153       mIndexBuffer             = new arr_type;
    00154       mPrimitiveRestartIndex   = typename arr_type::scalar_type(~0);
    00155       mPrimitiveRestartEnabled = false;
    00156       mBaseVertex              = 0;
    00157     }
    00158
    00159     DrawElements& operator=(const DrawElements& other)
    00160     {
    00161       DrawElementsBase::operator=(other);
    00162       *indices() = *other.indices();
    00163       mInstances = other.mInstances;
    00164       mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
    00165       mPrimitiveRestartIndex   = other.mPrimitiveRestartIndex;
    00166       mBaseVertex              = other.mBaseVertex;
    00167       return *this;
    00168     }
    00169
    00170     virtual ref<DrawCall> clone() const
    00171     {
    00172       ref<DrawElements> de = new DrawElements;
    00173       *de = *this;
    00174       return de;
    00175     }
    00176
    00177     virtual unsigned int handle() const { return indices()->gpuBuffer()->handle(); }
    00178
    00179     arr_type* indices() { return mIndexBuffer.get(); }
    00180
    00181     const arr_type* indices() const { return mIndexBuffer.get(); }
    00182
    00183     virtual void updateVBOs(bool discard_local_data=false, bool force_update=false)
    00184     {
    00185       if (indices()->isVBODirty() || force_update)
    00186         indices()->updateVBO(discard_local_data);
    00187     }
    00188
    00189     virtual void deleteVBOs()
    00190     {
    00191       indices()->gpuBuffer()->deleteGLBufferObject();
    00192     }
    00193
    00194     virtual void clearLocalBuffer()
    00195     {
    00196       indices()->gpuBuffer()->resize(0);
    00197     }
    00198
    00199     virtual void render(bool use_vbo) const
    00200     {
    00201       VL_CHECK(mBaseVertex>=0)
    00202       VL_CHECK(!use_vbo || (use_vbo && (GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0)))
    00203       use_vbo &= GLEW_ARB_vertex_buffer_object||GLEW_VERSION_1_5||GLEW_VERSION_3_0; // && indices()->gpuBuffer()->handle() && indices()->sizeGPU();
    00204       if ( !use_vbo && !indices()->size() )
    00205         return;
    00206
    00207       // apply patch parameters if any and if using PT_PATCHES
    00208       applyPatchParameters();
    00209
    00210       // primitive restart enable
    00211       if(primitiveRestartEnabled())
    00212       {
    00213         if(GLEW_VERSION_3_1)
    00214         {
    00215           glEnable(GL_PRIMITIVE_RESTART);
    00216           glPrimitiveRestartIndex(primitiveRestartIndex());
    00217         }
    00218         else
    00219         if(GLEW_NV_primitive_restart)
    00220         {
    00221           glEnable(GL_PRIMITIVE_RESTART_NV);
    00222           glPrimitiveRestartIndexNV(primitiveRestartIndex());
    00223         }
    00224         else
    00225         {
    00226           vl::Log::error("DrawElements error: primitive restart not supported by this OpenGL implementation!\n");
    00227           VL_TRAP();
    00228           return;
    00229         }
    00230       }
    00231
    00232       const GLvoid* ptr = indices()->gpuBuffer()->ptr();
    00233
    00234       if (use_vbo && indices()->gpuBuffer()->handle())
    00235       {
    00236         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indices()->gpuBuffer()->handle());
    00237         ptr = 0;
    00238       }
    00239       else
    00240         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    00241
    00242
    00243       if (mBaseVertex == 0)
    00244       {
    00245         if ( instances() > 1 && (GLEW_ARB_draw_instanced||GLEW_EXT_draw_instanced) )
    00246           VL_glDrawElementsInstanced( primitiveType(), use_vbo ? (GLsizei)indices()->sizeGPU() : (GLsizei)indices()->size(), indices()->glType(), ptr, (GLsizei)instances() );
    00247         else
    00248           glDrawElements( primitiveType(), use_vbo ? (GLsizei)indices()->sizeGPU() : (GLsizei)indices()->size(), indices()->glType(), ptr );
    00249       }
    00250       else
    00251       {
    00252         if ( instances() > 1 && (GLEW_ARB_draw_instanced||GLEW_EXT_draw_instanced) )
    00253           VL_glDrawElementsInstancedBaseVertex( primitiveType(), use_vbo ? (GLsizei)indices()->sizeGPU() : (GLsizei)indices()->size(), indices()->glType(), ptr, (GLsizei)instances(), mBaseVertex );
    00254         else
    00255           VL_glDrawElementsBaseVertex( primitiveType(), use_vbo ? (GLsizei)indices()->sizeGPU() : (GLsizei)indices()->size(), indices()->glType(), ptr, mBaseVertex );
    00256       }
    00257
    00258       // primitive restart disable
    00259
    00260       if(primitiveRestartEnabled())
    00261       {
    00262         if(GLEW_VERSION_3_1)
    00263           glDisable(GL_PRIMITIVE_RESTART);
    00264         else
    00265         if(GLEW_NV_primitive_restart)
    00266           glDisable(GL_PRIMITIVE_RESTART_NV);
    00267       }
    00268
    00269       #ifndef NDEBUG
    00270         unsigned int glerr = glGetError();
    00271         if (glerr != GL_NO_ERROR)
    00272         {
    00273           String msg( (char*)gluErrorString(glerr) );
    00274           Log::error( Say("glGetError() [%s:%n]: %s\n") << __FILE__ << __LINE__ << msg );
    00275           Log::print(
    00276             "OpenGL Geometry Instancing (GL_ARB_draw_instanced) does not support display lists."
    00277             "If you are using geometry instancing in conjunction with display lists you will have to disable one of them.\n"
    00278           );
    00279           VL_TRAP()
    00280         }
    00281       #endif
    00282     }
    00283
    00284     TriangleIterator triangleIterator() const
    00285     {
    00286       ref< TriangleIteratorIndexed<arr_type> > it =
    00287         new TriangleIteratorIndexed<arr_type>( mIndexBuffer.get(), primitiveType(),
    00288             baseVertex(), primitiveRestartEnabled(), primitiveRestartIndex() );
    00289       it->initialize();
    00290       return TriangleIterator(it.get());
    00291     }
    00292
    00293     IndexIterator indexIterator() const
    00294     {
    00295       ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
    00296       iie->initialize( mIndexBuffer.get(), NULL, NULL, mBaseVertex, mPrimitiveRestartEnabled, mPrimitiveRestartIndex );
    00297       IndexIterator iit;
    00298       iit.initialize( iie.get() );
    00299       return iit;
    00300     }
    00301
    00302   protected:
    00303     ref< arr_type > mIndexBuffer;
    00304   };
    00305   //------------------------------------------------------------------------------
    00306   // typedefs
    00307   //------------------------------------------------------------------------------
    00309   class DrawElementsUInt:  public DrawElements<GL_UNSIGNED_INT, ArrayUInt1>
    00310   {
    00311   public:
    00312     DrawElementsUInt(EPrimitiveType primitive = PT_TRIANGLES, int instances = 1)
    00313     :DrawElements<GL_UNSIGNED_INT, ArrayUInt1>(primitive, instances) {}
    00314   };
    00315   //------------------------------------------------------------------------------
    00317   class DrawElementsUShort: public DrawElements<GL_UNSIGNED_SHORT, ArrayUShort1>
    00318   {
    00319   public:
    00320     DrawElementsUShort(EPrimitiveType primitive = PT_TRIANGLES, int instances = 1)
    00321     :DrawElements<GL_UNSIGNED_SHORT, ArrayUShort1>(primitive, instances) {}
    00322   };
    00323   //------------------------------------------------------------------------------
    00325   class DrawElementsUByte:  public DrawElements<GL_UNSIGNED_BYTE, ArrayUByte1>
    00326   {
    00327   public:
    00328     DrawElementsUByte(EPrimitiveType primitive = PT_TRIANGLES, int instances = 1)
    00329     :DrawElements<GL_UNSIGNED_BYTE, ArrayUByte1>(primitive, instances) {}
    00330   };
    00331    //------------------------------------------------------------------------------
    00332 }
    00333
    00334 #endif

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