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