Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

OgreGLHardwareVertexBuffer.cpp

Go to the documentation of this file.
00001 /*
00002 -----------------------------------------------------------------------------
00003 This source file is part of OGRE
00004     (Object-oriented Graphics Rendering Engine)
00005 For the latest info, see http://www.ogre3d.org/
00006 
00007 Copyright © 2000-2003 The OGRE Team
00008 Also see acknowledgements in Readme.html
00009 
00010 This program is free software; you can redistribute it and/or modify it under
00011 the terms of the GNU Lesser General Public License as published by the Free Software
00012 Foundation; either version 2 of the License, or (at your option) any later
00013 version.
00014 
00015 This program is distributed in the hope that it will be useful, but WITHOUT
00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
00018 
00019 You should have received a copy of the GNU Lesser General Public License along with
00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
00022 http://www.gnu.org/copyleft/lesser.txt.
00023 -----------------------------------------------------------------------------
00024 */
00025 #include "OgreGLHardwareBufferManager.h"
00026 #include "OgreGLHardwareVertexBuffer.h"
00027 #include "OgreException.h"
00028 #include "OgreLogManager.h"
00029 
00030 namespace Ogre {
00031 
00032     //---------------------------------------------------------------------
00033     GLHardwareVertexBuffer::GLHardwareVertexBuffer(size_t vertexSize, 
00034         size_t numVertices, HardwareBuffer::Usage usage, bool useShadowBuffer)
00035         : HardwareVertexBuffer(vertexSize, numVertices, usage, false, useShadowBuffer)
00036     {
00037         glGenBuffersARB_ptr( 1, &mBufferId );
00038 
00039         if (!mBufferId)
00040         {
00041             Except(Exception::ERR_INTERNAL_ERROR, 
00042                 "Cannot create GL vertex buffer", 
00043                 "GLHardwareVertexBuffer::GLHardwareVertexBuffer");
00044         }
00045 
00046         glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, mBufferId);
00047 
00048         // Initialise mapped buffer and set usage
00049         glBufferDataARB_ptr(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 
00050             GLHardwareBufferManager::getGLUsage(usage));
00051 
00052         //std::cerr << "creating vertex buffer = " << mBufferId << std::endl;
00053     }
00054     //---------------------------------------------------------------------
00055     GLHardwareVertexBuffer::~GLHardwareVertexBuffer()
00056     {
00057         glDeleteBuffersARB_ptr(1, &mBufferId);
00058     }
00059     //---------------------------------------------------------------------
00060     void* GLHardwareVertexBuffer::lockImpl(size_t offset, 
00061         size_t length, LockOptions options)
00062     {
00063         GLenum access = 0;
00064 
00065         if(mIsLocked)
00066         {
00067             Except(Exception::ERR_INTERNAL_ERROR,
00068                 "Invalid attempt to lock an index buffer that has already been locked",
00069                 "GLHardwareIndexBuffer::lock");
00070         }
00071 
00072         glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, mBufferId);
00073 
00074         if(options == HBL_DISCARD)
00075         {
00076             //TODO: really we should use this to indicate our discard of the buffer
00077             //However it makes no difference to fps on nVidia, and can crash some ATI
00078             //glBufferDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 
00079             //    GLHardwareBufferManager::getGLUsage(mUsage));
00080 
00081             // TODO: we should be using the below implementation, but nVidia cards
00082             // choke on it and perform terribly - for investigation with nVidia
00083             //access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ? 
00084             //    GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
00085             access = GL_READ_WRITE;
00086 
00087         }
00088         else if(options == HBL_READ_ONLY)
00089         {
00090             if(mUsage == HBU_WRITE_ONLY)
00091             {
00092                 LogManager::getSingleton().logMessage(
00093                     "GLHardwareVertexBuffer: Locking a write-only vertex "
00094                     "buffer for reading, performance warning.");
00095             }
00096             access = GL_READ_ONLY_ARB;
00097         }
00098         else if(options == HBL_NORMAL || options == HBL_NO_OVERWRITE)
00099         {
00100             // TODO: we should be using the below implementation, but nVidia cards
00101             // choke on it and perform terribly - for investigation with nVidia
00102             //access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ? 
00103             //    GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
00104             access = GL_READ_WRITE;
00105         }
00106         else
00107         {
00108             Except(Exception::ERR_INTERNAL_ERROR, 
00109                 "Invalid locking option set", "GLHardwareVertexBuffer::lock");
00110         }
00111 
00112         void* pBuffer = glMapBufferARB_ptr( GL_ARRAY_BUFFER_ARB, access);
00113 
00114         if(pBuffer == 0)
00115         {
00116             Except(Exception::ERR_INTERNAL_ERROR, 
00117                 "Vertex Buffer: Out of memory", "GLHardwareVertexBuffer::lock");
00118         }
00119 
00120         mIsLocked = true;
00121         // return offsetted
00122         return static_cast<void*>(
00123             static_cast<unsigned char*>(pBuffer) + offset);
00124     }
00125     //---------------------------------------------------------------------
00126     void GLHardwareVertexBuffer::unlockImpl(void)
00127     {
00128         glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, mBufferId);
00129 
00130         if(!glUnmapBufferARB_ptr( GL_ARRAY_BUFFER_ARB ))
00131         {
00132             Except(Exception::ERR_INTERNAL_ERROR, 
00133                 "Buffer data corrupted, please reload", 
00134                 "GLHardwareVertexBuffer::unlock");
00135         }
00136 
00137         mIsLocked = false;
00138     }
00139     //---------------------------------------------------------------------
00140     void GLHardwareVertexBuffer::readData(size_t offset, size_t length, 
00141         void* pDest)
00142     {
00143         if(mUseShadowBuffer)
00144         {
00145             // get data from the shadow buffer
00146             void* srcData = mpShadowBuffer->lock(offset, length, HBL_READ_ONLY);
00147             memcpy(pDest, srcData, length);
00148             mpShadowBuffer->unlock();
00149         }
00150         else
00151         {
00152             // get data from the real buffer
00153             glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, mBufferId);
00154         
00155             glGetBufferSubDataARB_ptr(GL_ARRAY_BUFFER_ARB, offset, length, pDest);
00156         }
00157     }
00158     //---------------------------------------------------------------------
00159     void GLHardwareVertexBuffer::writeData(size_t offset, size_t length, 
00160             const void* pSource, bool discardWholeBuffer)
00161     {
00162         glBindBufferARB_ptr(GL_ARRAY_BUFFER_ARB, mBufferId);
00163 
00164         // Update the shadow buffer
00165         if(mUseShadowBuffer)
00166         {
00167             void* destData = mpShadowBuffer->lock(offset, length, 
00168                 discardWholeBuffer ? HBL_DISCARD : HBL_NORMAL);
00169             memcpy(destData, pSource, length);
00170             mpShadowBuffer->unlock();
00171         }
00172 
00173         if(discardWholeBuffer)
00174         {
00175             glBufferDataARB_ptr(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL, 
00176                 GLHardwareBufferManager::getGLUsage(mUsage));
00177         }
00178 
00179         // Now update the real buffer
00180         glBufferSubDataARB_ptr(GL_ARRAY_BUFFER_ARB, offset, length, pSource); 
00181     }
00182     //---------------------------------------------------------------------
00183 
00184 }

Copyright © 2002-2003 by The OGRE Team
Last modified Sun Nov 28 19:48:25 2004