Visualization Library

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

X:/dropbox/visualizationlibrary/src/vlGraphics/BufferObject.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 BufferObject_INCLUDE_ONCE
00033 #define BufferObject_INCLUDE_ONCE
00034 
00035 #include <vlCore/Vector2.hpp>
00036 #include <vlCore/Vector3.hpp>
00037 #include <vlCore/Vector4.hpp>
00038 #include <vlCore/Buffer.hpp>
00039 #include <vlGraphics/OpenGL.hpp>
00040 #include <vlCore/vlnamespace.hpp>
00041 #include <vlCore/Vector4.hpp>
00042 #include <vlCore/Sphere.hpp>
00043 #include <vlCore/AABB.hpp>
00044 
00045 namespace vl
00046 {
00047 //-----------------------------------------------------------------------------
00048 // BufferObject
00049 //-----------------------------------------------------------------------------
00055   class BufferObject: public Buffer
00056   {
00057     VL_INSTRUMENT_CLASS(vl::BufferObject, Buffer)
00058 
00059   public:
00060     BufferObject()
00061     {
00062       VL_DEBUG_SET_OBJECT_NAME()
00063       mHandle = 0;
00064       mUsage = BU_STATIC_DRAW;
00065       mByteCountBufferObject = 0;
00066     }
00067 
00068     BufferObject(const BufferObject& other): Buffer(other)
00069     {
00070       VL_DEBUG_SET_OBJECT_NAME()
00071       mHandle = 0;
00072       mUsage = BU_STATIC_DRAW;
00073       mByteCountBufferObject = 0;
00074       // copy local data
00075       *this = other;
00076     }
00077 
00078     // deletes the BufferObject data and copyes only the local data
00079     BufferObject& operator=(const BufferObject& other) 
00080     { 
00081       deleteBufferObject();
00082       super::operator=(other); 
00083       return *this;
00084     }
00085 
00086     // swaps data with another BufferObject, including BufferObject handle, usage and local data.
00087     void swap(BufferObject& other)
00088     {
00089       // swap local data
00090       Buffer::swap(other);
00091       // tmp
00092       unsigned int tmp_handle = mHandle;
00093       EBufferObjectUsage tmp_usage = mUsage;
00094       GLsizeiptr tmp_bytes = mByteCountBufferObject;
00095       // this <- other
00096       mHandle = other.mHandle;
00097       mUsage = tmp_usage;
00098       mByteCountBufferObject = other.mByteCountBufferObject;
00099       // other <- this
00100       other.mHandle = tmp_handle;
00101       other.mUsage = tmp_usage;
00102       other.mByteCountBufferObject = tmp_bytes;
00103     }
00104 
00105     ~BufferObject()
00106     {
00107       deleteBufferObject();
00108     }
00109 
00110     void setHandle(unsigned int handle) { mHandle = handle; }
00111 
00112     unsigned int handle() const { return mHandle; }
00113 
00114     GLsizeiptr byteCountBufferObject() const { return mByteCountBufferObject; }
00115 
00116     void createBufferObject()
00117     {
00118       VL_CHECK_OGL();
00119       VL_CHECK(Has_BufferObject)
00120       if (Has_BufferObject && handle() == 0)
00121       {
00122         VL_CHECK(mByteCountBufferObject == 0)
00123         VL_glGenBuffers( 1, &mHandle ); VL_CHECK_OGL();
00124         mByteCountBufferObject = 0;
00125         VL_CHECK(handle())
00126       }
00127     }
00128 
00129     void deleteBufferObject()
00130     {
00131       // mic fixme: it would be nice to re-enable these
00132       // VL_CHECK_OGL();
00133       VL_CHECK(Has_BufferObject || handle() == 0)
00134       if (Has_BufferObject && handle() != 0)
00135       {
00136         VL_glDeleteBuffers( 1, &mHandle ); // VL_CHECK_OGL();
00137         mHandle = 0;
00138         mByteCountBufferObject = 0;
00139       }
00140     }
00141 
00142     void downloadBufferObject()
00143     {
00144       VL_CHECK(Has_BufferObject)
00145       if ( Has_BufferObject && handle() )
00146       {
00147         resize( byteCountBufferObject() );
00148         void* vbo_ptr = mapBufferObject(BA_READ_ONLY);
00149         memcpy( ptr(), vbo_ptr, byteCountBufferObject() );
00150         unmapBufferObject();
00151       }
00152     }
00153 
00154     // Modifies the BufferObject using data from the local storage.
00155     // @note Discarding the local storage might delete data used by other Arrays.
00156     void setBufferData( EBufferObjectUsage usage, bool discard_local_storage=false )
00157     {
00158       setBufferData( (int)bytesUsed(), ptr(), usage );
00159       mUsage = usage;
00160       if (discard_local_storage)
00161         clear();
00162     }
00163 
00164     // Modifies the BufferObject using the supplied data.
00165     // @note Use this function to initialize or resize the BufferObject and set it's usage flag.
00166     // If data == NULL the buffer will be allocated but no data will be written to the BufferObject.
00167     // If data != NULL such data will be copied into the BufferObject.
00168     void setBufferData( GLsizeiptr byte_count, const GLvoid* data, EBufferObjectUsage usage )
00169     {
00170       VL_CHECK_OGL();
00171       VL_CHECK(Has_BufferObject)
00172       if ( Has_BufferObject )
00173       {
00174         createBufferObject();
00175         // we use the GL_ARRAY_BUFFER slot to send the data for no special reason
00176         VL_glBindBuffer( GL_ARRAY_BUFFER, handle() ); VL_CHECK_OGL();
00177         VL_glBufferData( GL_ARRAY_BUFFER, byte_count, data, usage ); VL_CHECK_OGL();
00178         VL_glBindBuffer( GL_ARRAY_BUFFER, 0 ); VL_CHECK_OGL();
00179         mByteCountBufferObject = byte_count;
00180         mUsage = usage;
00181       }
00182     }
00183 
00184     // Modifies an existing BufferObject using data from the local storage.
00185     // @note You can use this function only on already initialized BufferObjects, use setBufferData() to initialize a BufferObject.
00186     // @note Discarding the local storage might delete data used by other Arrays.
00187     void setBufferSubData( GLintptr offset=0, GLsizeiptr byte_count=-1, bool discard_local_storage=false )
00188     {
00189       byte_count = byte_count < 0 ? byteCountBufferObject() : byte_count;
00190       setBufferSubData( offset, byte_count, ptr() );
00191       if (discard_local_storage)
00192         clear();
00193     }
00194 
00195     // Modifies an existing BufferObject using the supplied data.
00196     // @note You can use this function only on already initialized BufferObjects, use setBufferData() to initialize a BufferObject.
00197     // @param[in] data Must be != NULL, pointer to the data being written to the BufferObject.
00198     void setBufferSubData( GLintptr offset, GLsizeiptr byte_count, const GLvoid* data )
00199     {
00200       VL_CHECK_OGL();
00201       VL_CHECK(Has_BufferObject)
00202       VL_CHECK(data);
00203       VL_CHECK(handle())
00204       if (Has_BufferObject && data && handle())
00205       {
00206         // we use the GL_ARRAY_BUFFER slot to send the data for no special reason
00207         VL_glBindBuffer( GL_ARRAY_BUFFER, handle() ); VL_CHECK_OGL();
00208         VL_glBufferSubData( GL_ARRAY_BUFFER, offset, byte_count, data ); VL_CHECK_OGL();
00209         VL_glBindBuffer( GL_ARRAY_BUFFER, 0 ); VL_CHECK_OGL();
00210       }
00211     }
00212 
00213     // Maps a BufferObject so that it can be read or written by the CPU.
00214     // @note You can map only one BufferObject at a time and you must unmap it before using the BufferObject again or mapping another one.
00215     void* mapBufferObject(EBufferObjectAccess access)
00216     {
00217       VL_CHECK_OGL();
00218       VL_CHECK(Has_BufferObject)
00219       if ( Has_BufferObject )
00220       {
00221         createBufferObject();
00222         VL_glBindBuffer( GL_ARRAY_BUFFER, handle() ); VL_CHECK_OGL();
00223         void* ptr = VL_glMapBuffer( GL_ARRAY_BUFFER, access ); VL_CHECK_OGL();
00224         VL_glBindBuffer( GL_ARRAY_BUFFER, 0 ); VL_CHECK_OGL();
00225         return ptr;
00226       }
00227       else
00228         return NULL;
00229     }
00230 
00231     // Unmaps a previously mapped BufferObject.
00232     // @return Returs true or false based on what's specified in the OpenGL specs:
00233     // "UnmapBuffer returns TRUE unless data values in the buffer’s data store have
00234     // become corrupted during the period that the buffer was mapped. Such corruption
00235     // can be the result of a screen resolution change or other window system-dependent
00236     // event that causes system heaps such as those for high-performance graphics memory
00237     // to be discarded. GL implementations must guarantee that such corruption can
00238     // occur only during the periods that a buffer’s data store is mapped. If such corruption
00239     // has occurred, UnmapBuffer returns FALSE, and the contents of the buffer’s
00240     // data store become undefined."
00241     bool unmapBufferObject()
00242     {
00243       VL_CHECK_OGL();
00244       VL_CHECK(Has_BufferObject)
00245       if ( Has_BufferObject )
00246       {
00247         createBufferObject();
00248         VL_glBindBuffer( GL_ARRAY_BUFFER, handle() ); VL_CHECK_OGL();
00249         bool ok = VL_glUnmapBuffer( GL_ARRAY_BUFFER ) == GL_TRUE; VL_CHECK_OGL();
00250         VL_glBindBuffer( GL_ARRAY_BUFFER, 0 ); VL_CHECK_OGL();
00251         VL_CHECK_OGL();
00252         return ok;
00253       }
00254       else
00255         return false;
00256     }
00257 
00259     EBufferObjectUsage usage() const { return mUsage; }
00260 
00261   protected:
00262     unsigned int mHandle;
00263     GLsizeiptr mByteCountBufferObject;
00264     EBufferObjectUsage mUsage;
00265   };
00266 }
00267 
00268 #endif

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