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