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

# OgreGLHardwareIndexBuffer.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 "OgreGLHardwareIndexBuffer.h"
    00026 #include "OgreGLHardwareBufferManager.h"
    00027 #include "OgreException.h"
    00028
    00029 namespace Ogre {
    00030
    00031     //---------------------------------------------------------------------
    00032     GLHardwareIndexBuffer::GLHardwareIndexBuffer(IndexType idxType,
    00033         size_t numIndexes, HardwareBuffer::Usage usage, bool useShadowBuffer)
    00034         : HardwareIndexBuffer(idxType, numIndexes, usage, false, useShadowBuffer)
    00035     {
    00036         glGenBuffersARB_ptr( 1, &mBufferId );
    00037
    00038         if (!mBufferId)
    00039         {
    00040             Except(Exception::ERR_INTERNAL_ERROR,
    00041                 "Cannot create GL index buffer",
    00042                 "GLHardwareIndexBuffer::GLHardwareIndexBuffer");
    00043         }
    00044
    00045         glBindBufferARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId);
    00046
    00047         // Initialise buffer and set usage
    00048         glBufferDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
    00049             GLHardwareBufferManager::getGLUsage(usage));
    00050
    00051         //std::cerr << "creating index buffer " << mBufferId << std::endl;
    00052     }
    00053     //---------------------------------------------------------------------
    00054     GLHardwareIndexBuffer::~GLHardwareIndexBuffer()
    00055     {
    00056         glDeleteBuffersARB_ptr(1, &mBufferId);
    00057     }
    00058     //---------------------------------------------------------------------
    00059     void* GLHardwareIndexBuffer::lockImpl(size_t offset,
    00060         size_t length, LockOptions options)
    00061     {
    00062         GLenum access = 0;
    00063
    00064         if(mIsLocked)
    00065         {
    00066             Except(Exception::ERR_INTERNAL_ERROR,
    00067                 "Invalid attempt to lock an index buffer that has already been locked",
    00068                     "GLHardwareIndexBuffer::lock");
    00069         }
    00070
    00071         glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
    00072
    00073         if(options == HBL_DISCARD)
    00074         {
    00075             //TODO: really we should use this to indicate our discard of the buffer
    00076             //However it makes no difference to fps on nVidia, and can crash some ATI
    00077             //glBufferDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
    00078             //    GLHardwareBufferManager::getGLUsage(mUsage));
    00079
    00080             // TODO: we should be using the below implementation, but nVidia cards
    00081             // choke on it and perform terribly - for investigation with nVidia
    00082             access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
    00083                 GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
    00084             //access = GL_READ_WRITE;
    00085         }
    00086         else if(options == HBL_READ_ONLY)
    00087         {
    00088             if(mUsage == HBU_WRITE_ONLY)
    00089             {
    00090                 Except(Exception::ERR_INTERNAL_ERROR,
    00091                     "Invalid attempt to lock a write-only index buffer as read-only",
    00092                     "GLHardwareIndexBuffer::lock");
    00093             }
    00094             access = GL_READ_ONLY_ARB;
    00095         }
    00096         else if(options == HBL_NORMAL || options == HBL_NO_OVERWRITE)
    00097         {
    00098             // TODO: we should be using the below implementation, but nVidia cards
    00099             // choke on it and perform terribly - for investigation with nVidia
    00100             access = (mUsage == HBU_DYNAMIC || mUsage == HBU_STATIC) ?
    00101                 GL_READ_WRITE_ARB : GL_WRITE_ONLY_ARB;
    00102             //access = GL_READ_WRITE;
    00103         }
    00104         else
    00105         {
    00106             Except(Exception::ERR_INTERNAL_ERROR,
    00107                 "Invalid locking option set", "GLHardwareIndexBuffer::lock");
    00108         }
    00109
    00110         void* pBuffer = glMapBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, access );
    00111
    00112         if(pBuffer == 0)
    00113         {
    00114             Except(Exception::ERR_INTERNAL_ERROR,
    00115                 "Index Buffer: Out of memory",
    00116                 "GLHardwareIndexBuffer::lock");
    00117         }
    00118
    00119         mIsLocked = true;
    00120         // return offsetted
    00121         return static_cast<void*>(
    00122             static_cast<unsigned char*>(pBuffer) + offset);
    00123     }
    00124     //---------------------------------------------------------------------
    00125     void GLHardwareIndexBuffer::unlockImpl(void)
    00126     {
    00127         glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
    00128
    00129         if(!glUnmapBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB ))
    00130         {
    00131             Except(Exception::ERR_INTERNAL_ERROR,
    00132                 "Buffer data corrupted, please reload",
    00133                 "GLHardwareIndexBuffer::unlock");
    00134         }
    00135
    00136         mIsLocked = false;
    00137     }
    00138     //---------------------------------------------------------------------
    00139     void GLHardwareIndexBuffer::readData(size_t offset, size_t length,
    00140         void* pDest)
    00141     {
    00142         if(mUseShadowBuffer)
    00143         {
    00144             // get data from the shadow buffer
    00145             void* srcData = mpShadowBuffer->lock(offset, length, HBL_READ_ONLY);
    00146             memcpy(pDest, srcData, length);
    00147             mpShadowBuffer->unlock();
    00148         }
    00149         else
    00150         {
    00151             glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
    00152             glGetBufferSubDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pDest);
    00153         }
    00154     }
    00155     //---------------------------------------------------------------------
    00156     void GLHardwareIndexBuffer::writeData(size_t offset, size_t length,
    00157             const void* pSource, bool discardWholeBuffer)
    00158     {
    00159         glBindBufferARB_ptr( GL_ELEMENT_ARRAY_BUFFER_ARB, mBufferId );
    00160
    00161         // Update the shadow buffer
    00162         if(mUseShadowBuffer)
    00163         {
    00164             void* destData = mpShadowBuffer->lock(offset, length,
    00165                 discardWholeBuffer ? HBL_DISCARD : HBL_NORMAL);
    00166             memcpy(destData, pSource, length);
    00167             mpShadowBuffer->unlock();
    00168         }
    00169
    00170         if(discardWholeBuffer)
    00171         {
    00172             glBufferDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
    00173                 GLHardwareBufferManager::getGLUsage(mUsage));
    00174         }
    00175
    00176         // Now update the real buffer
    00177         glBufferSubDataARB_ptr(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length, pSource);
    00178     }
    00179     //---------------------------------------------------------------------
    00180 }

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