Visualization Library

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

X:/dropbox/visualizationlibrary/src/vlGraphics/DrawRangeElements.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 DrawRangeElements_INCLUDE_ONCE
00033 #define DrawRangeElements_INCLUDE_ONCE
00034 
00035 #include <vlGraphics/DrawCall.hpp>
00036 #include <vlGraphics/TriangleIterator.hpp>
00037 #include <vlGraphics/LineIterator.hpp>
00038 #include <vlGraphics/Array.hpp>
00039 #include <vlCore/Log.hpp>
00040 #include <vlCore/Say.hpp>
00041 #include <algorithm>
00042 
00043 namespace vl
00044 {
00045 
00046   //------------------------------------------------------------------------------
00047   // DrawRangeElementsBase
00048   //------------------------------------------------------------------------------
00054   class DrawRangeElementsBase: public DrawCall
00055   {
00056     VL_INSTRUMENT_ABSTRACT_CLASS(vl::DrawRangeElementsBase, DrawCall)
00057 
00058   public:
00060     void setRangeStart(int rstart) { mRangeStart = rstart; }
00061 
00063     int rangeStart() const { return mRangeStart; }
00064 
00066     void setRangeEnd(int rend) { mRangeEnd = rend; }
00067 
00069     int rangeEnd() const { return mRangeEnd; }
00070 
00072     virtual bool primitiveRestartEnabled() const { return mPrimitiveRestartEnabled; }
00073 
00075     void setPrimitiveRestartEnabled(bool enabled) { mPrimitiveRestartEnabled = enabled; }
00076 
00081     void setBaseVertex(int base_vertex) { mBaseVertex = base_vertex; }
00082 
00085     int  baseVertex() const { return mBaseVertex; }
00086 
00087   protected:
00088     int mRangeStart;
00089     int mRangeEnd;
00090     GLuint mBaseVertex;
00091     bool mPrimitiveRestartEnabled;
00092   };
00093   //------------------------------------------------------------------------------
00094   // DrawRangeElements
00095   //------------------------------------------------------------------------------
00120   template <class arr_type>
00121   class DrawRangeElements: public DrawRangeElementsBase
00122   {
00123     VL_INSTRUMENT_CLASS(vl::DrawRangeElements<arr_type>, DrawRangeElementsBase)
00124 
00125   public:
00126     typedef typename arr_type::scalar_type index_type;
00128     static const index_type primitive_restart_index = index_type(~0);
00129     virtual unsigned int primitiveRestartIndex() { return (unsigned int)primitive_restart_index; }
00130 
00131   private:
00132     template<typename T>
00133     class Triangle
00134     {
00135     public:
00136       T ABC[3];
00137       bool operator<(const Triangle<index_type>& b) const
00138       {
00139         if (ABC[0] != b.ABC[0])
00140           return ABC[0] < b.ABC[0];
00141         else
00142         if (ABC[1] != b.ABC[1])
00143           return ABC[1] < b.ABC[1];
00144         else
00145           return ABC[2] < b.ABC[2];
00146       }
00147       void rotate()
00148       {
00149         if (ABC[0] > ABC[1])
00150           { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
00151         if (ABC[0] > ABC[1])
00152           { T tmp = ABC[0]; ABC[0] = ABC[1]; ABC[1] = ABC[2]; ABC[2] = tmp; }
00153       }
00154     };
00155 
00156   public:
00157     DrawRangeElements(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=primitive_restart_index)
00158     {
00159       VL_DEBUG_SET_OBJECT_NAME()
00160       mType                    = primitive;
00161       mRangeStart              = r_start;
00162       mRangeEnd                = r_end;
00163       mIndexBuffer             = new arr_type;
00164       mPrimitiveRestartEnabled = false;
00165       mBaseVertex              = 0;
00166       mCount                   = -1; // till the end of the indexBuffer()
00167       mOffset                  = 0; // from the beginning of the indexBuffer()
00168     }
00169 
00170     DrawRangeElements& operator=(const DrawRangeElements& other)
00171     {
00172       super::operator=(other);
00173       *indexBuffer()               = *other.indexBuffer();
00174       mRangeStart              = other.mRangeStart;
00175       mRangeEnd                = other.mRangeEnd;
00176       mPrimitiveRestartEnabled = other.mPrimitiveRestartEnabled;
00177       mBaseVertex              = other.mBaseVertex;
00178       mCount                   = other.mCount;
00179       mOffset                  = other.mOffset;
00180       return *this;
00181     }
00182 
00183     virtual ref<DrawCall> clone() const 
00184     { 
00185       ref<DrawRangeElements> de = new DrawRangeElements;
00186       *de = *this;
00187       return de;
00188     }
00189 
00191     void setCount(i32 count) { mCount = count; }
00192 
00194     i32 count() const { return mCount; }
00195 
00197     void setOffset(u32 offset) { mOffset = offset; }
00198 
00200     u32 offset() const { return mOffset; }
00201 
00203     void setIndexBuffer(arr_type* index_buffer) { mIndexBuffer = index_buffer; }
00204 
00206     arr_type* indexBuffer() { return mIndexBuffer.get(); }
00207 
00209     const arr_type* indexBuffer() const { return mIndexBuffer.get(); }
00210 
00211     virtual void updateDirtyBufferObject(EBufferObjectUpdateMode mode)
00212     {
00213       if (indexBuffer()->isBufferObjectDirty() || (mode & BUF_ForceUpdate))
00214         indexBuffer()->updateBufferObject(mode);
00215     }
00216 
00217     virtual void deleteBufferObject()
00218     {
00219       indexBuffer()->bufferObject()->deleteBufferObject();
00220     }
00221 
00222     virtual void render(bool use_bo) const
00223     {
00224       VL_CHECK_OGL()
00225       VL_CHECK(!use_bo || (use_bo && Has_BufferObject))
00226       use_bo &= Has_BufferObject; // && indexBuffer()->bufferObject()->handle() && indexBuffer()->sizeBufferObject();
00227       if ( !use_bo && !indexBuffer()->size() )
00228         return;
00229 
00230       // apply patch parameters if any and if using PT_PATCHES
00231       applyPatchParameters();
00232 
00233       // primitive restart enable
00234       if(primitiveRestartEnabled())
00235       {
00236         VL_CHECK(Has_Primitive_Restart);
00237         glEnable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL();
00238         glPrimitiveRestartIndex(primitive_restart_index); VL_CHECK_OGL();
00239       }
00240 
00241       // compute base pointer
00242 
00243       const GLvoid* ptr = indexBuffer()->bufferObject()->ptr();
00244       if (use_bo && indexBuffer()->bufferObject()->handle())
00245       {
00246         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer()->bufferObject()->handle()); VL_CHECK_OGL()
00247         ptr = 0;
00248       }
00249       else
00250       {
00251         VL_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); VL_CHECK_OGL()
00252       }
00253 
00254       // compute final pointer and count
00255 
00256       const char*ptr_end = NULL;
00257       if(mCount < 0)
00258       {
00259         // compute the end of the index buffer
00260         ptr_end = (char*)ptr + sizeof(index_type)*(use_bo ? indexBuffer()->sizeBufferObject() : indexBuffer()->size());
00261 
00262         // offset in the index buffer
00263         ptr = (char*)ptr + mOffset;
00264       }
00265       else
00266       {
00267         // offset in the index buffer
00268         ptr = (char*)ptr + mOffset;
00269 
00270         // compute the end of the indices
00271         ptr_end = (char*)ptr + sizeof(index_type)*mCount;
00272       }
00273 
00274       // compute the remaining indices
00275       const GLsizei count = (GLsizei)((index_type*)ptr_end - (index_type*)ptr);
00276 
00277       if (mBaseVertex == 0)
00278       {
00279         glDrawRangeElements( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr ); VL_CHECK_OGL()
00280       }
00281       else
00282       {
00283         VL_CHECK(Has_Base_Vertex)
00284         VL_glDrawRangeElementsBaseVertex( primitiveType(), mRangeStart, mRangeEnd, count, arr_type::gl_type, ptr, mBaseVertex ); VL_CHECK_OGL()
00285       }
00286 
00287       // primitive restart disable
00288 
00289       if(primitiveRestartEnabled())
00290       {
00291         glDisable(GL_PRIMITIVE_RESTART); VL_CHECK_OGL()
00292       }
00293     }
00294 
00295     TriangleIterator triangleIterator() const
00296     {
00297       ref< TriangleIteratorIndexed<arr_type> > it = 
00298         new TriangleIteratorIndexed<arr_type>( mIndexBuffer.get(), primitiveType(), 
00299             baseVertex(), primitiveRestartEnabled(), primitive_restart_index );
00300       it->initialize();
00301       return TriangleIterator(it.get());
00302     }
00303 
00304     LineIterator lineIterator() const
00305     {
00306       ref< LineIteratorIndexed<arr_type> > it =
00307         new LineIteratorIndexed<arr_type>( mIndexBuffer.get(), primitiveType(),
00308             baseVertex(), primitiveRestartEnabled(), primitive_restart_index );
00309       it->initialize();
00310       return LineIterator(it.get());
00311     }
00312 
00313     IndexIterator indexIterator() const
00314     {
00315       ref< IndexIteratorElements<arr_type> > iie = new IndexIteratorElements<arr_type>;
00316       iie->initialize( mIndexBuffer.get(), NULL, NULL, mBaseVertex, mPrimitiveRestartEnabled, primitive_restart_index );
00317       IndexIterator iit;
00318       iit.initialize( iie.get() );
00319       return iit;
00320     }
00321 
00322     void computeRange()
00323     {
00324       mRangeStart = primitive_restart_index;
00325       mRangeEnd   = 0;
00326 
00327       for(IndexIterator it=indexIterator(); it.hasNext(); it.next())
00328       {
00329         if (it.index() < mRangeStart)
00330           mRangeStart = it.index();
00331         if (it.index() > mRangeEnd)
00332           mRangeEnd   = it.index();
00333       }
00334 
00335       if (mRangeEnd < mRangeStart)
00336       {
00337         mRangeStart = 0;
00338         mRangeEnd   = primitive_restart_index;
00339       }
00340     }
00341 
00342   protected:
00343     ref< arr_type > mIndexBuffer;
00344     i32 mCount;
00345     u32 mOffset;
00346   };
00347   //------------------------------------------------------------------------------
00348   // typedefs
00349   //------------------------------------------------------------------------------
00351   class DrawRangeElementsUInt: public DrawRangeElements<ArrayUInt1>
00352   {
00353     VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUInt, DrawRangeElements<ArrayUInt1>)
00354 
00355   public:
00356     DrawRangeElementsUInt(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLuint(~0))
00357     :DrawRangeElements<ArrayUInt1>(primitive, r_start, r_end)
00358     {
00359       VL_DEBUG_SET_OBJECT_NAME();
00360     }
00361   };
00362   //------------------------------------------------------------------------------
00364   class DrawRangeElementsUShort: public DrawRangeElements<ArrayUShort1>
00365   {
00366     VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUShort, DrawRangeElements<ArrayUShort1>)
00367 
00368   public:
00369     DrawRangeElementsUShort(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLushort(~0))
00370     :DrawRangeElements<ArrayUShort1>(primitive, r_start, r_end)
00371     {
00372       VL_DEBUG_SET_OBJECT_NAME();
00373     }
00374   };
00375   //------------------------------------------------------------------------------
00377   class DrawRangeElementsUByte: public DrawRangeElements<ArrayUByte1>
00378   {
00379     VL_INSTRUMENT_CLASS(vl::DrawRangeElementsUByte, DrawRangeElements<ArrayUByte1>)
00380 
00381   public:
00382     DrawRangeElementsUByte(EPrimitiveType primitive = PT_TRIANGLES, int r_start=0, int r_end=GLubyte(~0))
00383     :DrawRangeElements<ArrayUByte1>(primitive, r_start, r_end)
00384     {
00385       VL_DEBUG_SET_OBJECT_NAME();
00386     }
00387   };
00388   //------------------------------------------------------------------------------
00389 }
00390 
00391 #endif

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