| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
- //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
- #include "BsGLBuffer.h"
- #include "BsGLHardwareBufferManager.h"
- #include "Error/BsException.h"
- namespace bs { namespace ct
- {
- GLBuffer::GLBuffer()
- :mTarget(0), mBufferId(0), mZeroLocked(false)
- {
-
- }
- GLBuffer::GLBuffer(GLenum target, UINT32 size, GpuBufferUsage usage)
- :mTarget(target), mBufferId(0), mZeroLocked(false)
- {
- initialize(target, size, usage);
- }
- GLBuffer::~GLBuffer()
- {
- if (mBufferId != 0)
- {
- glDeleteBuffers(1, &mBufferId);
- BS_CHECK_GL_ERROR();
- }
- }
- void GLBuffer::initialize(GLenum target, UINT32 size, GpuBufferUsage usage)
- {
- assert(mBufferId == 0 && "Buffer already initialized");
- mTarget = target;
- glGenBuffers(1, &mBufferId);
- BS_CHECK_GL_ERROR();
- if (!mBufferId)
- BS_EXCEPT(InternalErrorException, "Cannot create GL vertex buffer");
- glBindBuffer(target, mBufferId);
- BS_CHECK_GL_ERROR();
- glBufferData(target, size, nullptr, GLHardwareBufferManager::getGLUsage(usage));
- BS_CHECK_GL_ERROR();
- }
- void* GLBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
- {
- GLenum access = 0;
- glBindBuffer(mTarget, mBufferId);
- BS_CHECK_GL_ERROR();
- if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
- {
- 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;
- }
- else if (options == GBL_READ_ONLY)
- access = GL_MAP_READ_BIT;
- else
- access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
- void* buffer = nullptr;
- if (length > 0)
- {
- buffer = glMapBufferRange(mTarget, offset, length, access);
- BS_CHECK_GL_ERROR();
- if (buffer == nullptr)
- BS_EXCEPT(InternalErrorException, "Cannot map OpenGL buffer.");
- mZeroLocked = false;
- }
- else
- mZeroLocked = true;
- return static_cast<void*>(static_cast<unsigned char*>(buffer));
- }
- void GLBuffer::unlock()
- {
- glBindBuffer(mTarget, mBufferId);
- BS_CHECK_GL_ERROR();
- if (!mZeroLocked)
- {
- if (!glUnmapBuffer(mTarget))
- {
- BS_CHECK_GL_ERROR();
- BS_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload.");
- }
- }
- }
- void GLBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
- {
- void* bufferData = lock(offset, length, GBL_READ_ONLY);
- memcpy(pDest, bufferData, length);
- unlock();
- }
- void GLBuffer::writeData(UINT32 offset, UINT32 length,
- const void* pSource, BufferWriteType writeFlags)
- {
- GpuLockOptions lockOption = GBL_WRITE_ONLY;
- if (writeFlags == BWT_DISCARD)
- lockOption = GBL_WRITE_ONLY_DISCARD;
- else if (writeFlags == BTW_NO_OVERWRITE)
- lockOption = GBL_WRITE_ONLY_NO_OVERWRITE;
- void* bufferData = lock(offset, length, lockOption);
- memcpy(bufferData, pSource, length);
- unlock();
- }
- void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length)
- {
- glBindBuffer(GL_COPY_READ_BUFFER, getGLBufferId());
- BS_CHECK_GL_ERROR();
- glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
- BS_CHECK_GL_ERROR();
- glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
- BS_CHECK_GL_ERROR();
- }
- }}
|