|
|
@@ -29,19 +29,18 @@ THE SOFTWARE.
|
|
|
#include "CmGLVertexBuffer.h"
|
|
|
#include "CmException.h"
|
|
|
|
|
|
-namespace CamelotFramework {
|
|
|
-
|
|
|
- //---------------------------------------------------------------------
|
|
|
+namespace CamelotFramework
|
|
|
+{
|
|
|
GLVertexBuffer::GLVertexBuffer(HardwareBufferManager* mgr, UINT32 vertexSize,
|
|
|
UINT32 numVertices, GpuBufferUsage usage)
|
|
|
: VertexBuffer(mgr, vertexSize, numVertices, usage, false)
|
|
|
{
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
GLVertexBuffer::~GLVertexBuffer()
|
|
|
{
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
void* GLVertexBuffer::lockImpl(UINT32 offset,
|
|
|
UINT32 length, GpuLockOptions options)
|
|
|
{
|
|
|
@@ -50,138 +49,74 @@ namespace CamelotFramework {
|
|
|
if(mIsLocked)
|
|
|
{
|
|
|
CM_EXCEPT(InternalErrorException,
|
|
|
- "Invalid attempt to lock an index buffer that has already been locked");
|
|
|
+ "Invalid attempt to lock a vertex buffer that has already been locked");
|
|
|
}
|
|
|
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
|
|
|
|
|
|
- void* retPtr = 0;
|
|
|
-
|
|
|
- GLHardwareBufferManager* glBufManager = static_cast<GLHardwareBufferManager*>(HardwareBufferManager::instancePtr());
|
|
|
-
|
|
|
- // Try to use scratch buffers for smaller buffers
|
|
|
- if( length < glBufManager->getGLMapBufferThreshold() )
|
|
|
+ if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
|
|
|
{
|
|
|
- // if this fails, we fall back on mapping
|
|
|
- retPtr = glBufManager->allocateScratch((UINT32)length);
|
|
|
-
|
|
|
- if (retPtr)
|
|
|
- {
|
|
|
- mLockedToScratch = true;
|
|
|
- mScratchOffset = offset;
|
|
|
- mScratchSize = length;
|
|
|
- mScratchPtr = retPtr;
|
|
|
- mScratchUploadOnUnlock = (options != GBL_READ_ONLY);
|
|
|
-
|
|
|
- if (options != GBL_WRITE_ONLY_DISCARD)
|
|
|
- {
|
|
|
- // have to read back the data before returning the pointer
|
|
|
- readData(offset, length, retPtr);
|
|
|
- }
|
|
|
- }
|
|
|
+ access = GL_MAP_WRITE_BIT;
|
|
|
+
|
|
|
+ if(options == GBL_WRITE_ONLY_DISCARD)
|
|
|
+ access |= GL_MAP_INVALIDATE_BUFFER_BIT;
|
|
|
+ else if(options == GBL_WRITE_ONLY_NO_OVERWRITE)
|
|
|
+ access |= GL_MAP_UNSYNCHRONIZED_BIT;
|
|
|
}
|
|
|
-
|
|
|
- if (!retPtr)
|
|
|
+ else if (options == GBL_READ_ONLY)
|
|
|
+ access = GL_MAP_READ_BIT;
|
|
|
+ else
|
|
|
+ access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
|
|
|
+
|
|
|
+ void* pBuffer = glMapBufferRange(GL_ARRAY_BUFFER, offset, length, access);
|
|
|
+
|
|
|
+ if(pBuffer == 0)
|
|
|
{
|
|
|
- // Use glMapBuffer
|
|
|
- glBindBufferARB( GL_ARRAY_BUFFER_ARB, mBufferId );
|
|
|
- // Use glMapBuffer
|
|
|
- if(options == GBL_WRITE_ONLY_DISCARD)
|
|
|
- {
|
|
|
- // Discard the buffer
|
|
|
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
|
|
|
- GLHardwareBufferManager::getGLUsage(mUsage));
|
|
|
-
|
|
|
- }
|
|
|
- if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE))
|
|
|
- access = GL_WRITE_ONLY_ARB;
|
|
|
- else if (options == GBL_READ_ONLY)
|
|
|
- access = GL_READ_ONLY_ARB;
|
|
|
- else
|
|
|
- access = GL_READ_WRITE_ARB;
|
|
|
-
|
|
|
- void* pBuffer = glMapBufferARB( GL_ARRAY_BUFFER_ARB, access);
|
|
|
-
|
|
|
- if(pBuffer == 0)
|
|
|
- {
|
|
|
- CM_EXCEPT(InternalErrorException, "Vertex Buffer: Out of memory");
|
|
|
- }
|
|
|
-
|
|
|
- // return offsetted
|
|
|
- retPtr = static_cast<void*>(
|
|
|
- static_cast<unsigned char*>(pBuffer) + offset);
|
|
|
-
|
|
|
- mLockedToScratch = false;
|
|
|
+ CM_EXCEPT(InternalErrorException, "Vertex Buffer: Out of memory");
|
|
|
}
|
|
|
+
|
|
|
+ void* retPtr = static_cast<void*>(static_cast<unsigned char*>(pBuffer) + offset);
|
|
|
+
|
|
|
mIsLocked = true;
|
|
|
return retPtr;
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
void GLVertexBuffer::unlockImpl(void)
|
|
|
{
|
|
|
- if (mLockedToScratch)
|
|
|
- {
|
|
|
- if (mScratchUploadOnUnlock)
|
|
|
- {
|
|
|
- // have to write the data back to vertex buffer
|
|
|
- writeData(mScratchOffset, mScratchSize, mScratchPtr,
|
|
|
- mScratchOffset == 0 && mScratchSize == getSizeInBytes());
|
|
|
- }
|
|
|
-
|
|
|
- // deallocate from scratch buffer
|
|
|
- static_cast<GLHardwareBufferManager*>(
|
|
|
- HardwareBufferManager::instancePtr())->deallocateScratch(mScratchPtr);
|
|
|
-
|
|
|
- mLockedToScratch = false;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
-
|
|
|
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
|
|
|
|
|
|
- if(!glUnmapBufferARB( GL_ARRAY_BUFFER_ARB ))
|
|
|
- {
|
|
|
- CM_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload");
|
|
|
- }
|
|
|
+ if(!glUnmapBuffer(GL_ARRAY_BUFFER))
|
|
|
+ {
|
|
|
+ CM_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload");
|
|
|
}
|
|
|
|
|
|
mIsLocked = false;
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
- void GLVertexBuffer::readData(UINT32 offset, UINT32 length,
|
|
|
- void* pDest)
|
|
|
+
|
|
|
+ void GLVertexBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
|
|
|
{
|
|
|
- // get data from the real buffer
|
|
|
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
|
|
|
-
|
|
|
- glGetBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pDest);
|
|
|
+ void* bufferData = lock(offset, length, GBL_READ_ONLY);
|
|
|
+ memcpy(pDest, bufferData, length);
|
|
|
+ unlock();
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
void GLVertexBuffer::writeData(UINT32 offset, UINT32 length,
|
|
|
- const void* pSource, bool discardWholeBuffer)
|
|
|
+ const void* pSource, BufferWriteType writeFlags)
|
|
|
{
|
|
|
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
|
|
|
-
|
|
|
- if (offset == 0 && length == mSizeInBytes)
|
|
|
- {
|
|
|
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, pSource,
|
|
|
- GLHardwareBufferManager::getGLUsage(mUsage));
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- if(discardWholeBuffer)
|
|
|
- {
|
|
|
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
|
|
|
- GLHardwareBufferManager::getGLUsage(mUsage));
|
|
|
- }
|
|
|
-
|
|
|
- // Now update the real buffer
|
|
|
- glBufferSubDataARB(GL_ARRAY_BUFFER_ARB, offset, length, pSource);
|
|
|
- }
|
|
|
+ GpuLockOptions lockOption = GBL_WRITE_ONLY;
|
|
|
+ if(writeFlags == BufferWriteType::Discard)
|
|
|
+ lockOption = GBL_WRITE_ONLY_DISCARD;
|
|
|
+ else if(writeFlags == BufferWriteType::NoOverwrite)
|
|
|
+ lockOption = GBL_WRITE_ONLY_NO_OVERWRITE;
|
|
|
+
|
|
|
+ void* bufferData = lock(offset, length, lockOption);
|
|
|
+ memcpy(bufferData, pSource, length);
|
|
|
+ unlock();
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
void GLVertexBuffer::initialize_internal()
|
|
|
{
|
|
|
- glGenBuffersARB( 1, &mBufferId );
|
|
|
+ glGenBuffers(1, &mBufferId);
|
|
|
|
|
|
if (!mBufferId)
|
|
|
{
|
|
|
@@ -189,18 +124,18 @@ namespace CamelotFramework {
|
|
|
"Cannot create GL vertex buffer");
|
|
|
}
|
|
|
|
|
|
- glBindBufferARB(GL_ARRAY_BUFFER_ARB, mBufferId);
|
|
|
+ glBindBuffer(GL_ARRAY_BUFFER, mBufferId);
|
|
|
|
|
|
// Initialise mapped buffer and set usage
|
|
|
- glBufferDataARB(GL_ARRAY_BUFFER_ARB, mSizeInBytes, NULL,
|
|
|
+ glBufferData(GL_ARRAY_BUFFER, mSizeInBytes, NULL,
|
|
|
GLHardwareBufferManager::getGLUsage(mUsage));
|
|
|
|
|
|
VertexBuffer::initialize_internal();
|
|
|
}
|
|
|
- //---------------------------------------------------------------------
|
|
|
+
|
|
|
void GLVertexBuffer::destroy_internal()
|
|
|
{
|
|
|
- glDeleteBuffersARB(1, &mBufferId);
|
|
|
+ glDeleteBuffers(1, &mBufferId);
|
|
|
|
|
|
VertexBuffer::destroy_internal();
|
|
|
}
|