Visualization Library v1.0.3A lightweight C++ OpenGL middleware for 2D/3D graphics |
[Download] [Tutorials] [All Classes] [Grouped Classes] |
00001 /**************************************************************************************/ 00002 /* */ 00003 /* Visualization Library */ 00004 /* http://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