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_ARRAY_BUFFER_ARB, mBufferId);
00046 
00047         // Initialise buffer and set usage
00048         glBufferDataARB_ptr(GL_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 Fri May 14 23:22:11 2004