BsGLBuffer.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsGLBuffer.h"
  4. #include "BsGLHardwareBufferManager.h"
  5. #include "Error/BsException.h"
  6. namespace bs { namespace ct
  7. {
  8. GLBuffer::GLBuffer()
  9. :mTarget(0), mBufferId(0), mZeroLocked(false)
  10. {
  11. }
  12. GLBuffer::GLBuffer(GLenum target, UINT32 size, GpuBufferUsage usage)
  13. :mTarget(target), mBufferId(0), mZeroLocked(false)
  14. {
  15. initialize(target, size, usage);
  16. }
  17. GLBuffer::~GLBuffer()
  18. {
  19. if(mBufferId != 0)
  20. glDeleteBuffers(1, &mBufferId);
  21. }
  22. void GLBuffer::initialize(GLenum target, UINT32 size, GpuBufferUsage usage)
  23. {
  24. assert(mBufferId == 0 && "Buffer already initialized");
  25. mTarget = target;
  26. glGenBuffers(1, &mBufferId);
  27. if (!mBufferId)
  28. {
  29. BS_EXCEPT(InternalErrorException, "Cannot create GL vertex buffer");
  30. }
  31. glBindBuffer(target, mBufferId);
  32. glBufferData(target, size, nullptr, GLHardwareBufferManager::getGLUsage(usage));
  33. }
  34. void* GLBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
  35. {
  36. GLenum access = 0;
  37. glBindBuffer(mTarget, mBufferId);
  38. if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
  39. {
  40. access = GL_MAP_WRITE_BIT;
  41. if (options == GBL_WRITE_ONLY_DISCARD)
  42. access |= GL_MAP_INVALIDATE_BUFFER_BIT;
  43. else if (options == GBL_WRITE_ONLY_NO_OVERWRITE)
  44. access |= GL_MAP_UNSYNCHRONIZED_BIT;
  45. }
  46. else if (options == GBL_READ_ONLY)
  47. access = GL_MAP_READ_BIT;
  48. else
  49. access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
  50. void* buffer = nullptr;
  51. if (length > 0)
  52. {
  53. buffer = glMapBufferRange(mTarget, offset, length, access);
  54. if (buffer == nullptr)
  55. {
  56. BS_EXCEPT(InternalErrorException, "Cannot map OpenGL buffer.");
  57. }
  58. mZeroLocked = false;
  59. }
  60. else
  61. mZeroLocked = true;
  62. return static_cast<void*>(static_cast<unsigned char*>(buffer));
  63. }
  64. void GLBuffer::unlock()
  65. {
  66. glBindBuffer(mTarget, mBufferId);
  67. if (!mZeroLocked)
  68. {
  69. if (!glUnmapBuffer(mTarget))
  70. {
  71. BS_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload.");
  72. }
  73. }
  74. }
  75. void GLBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
  76. {
  77. void* bufferData = lock(offset, length, GBL_READ_ONLY);
  78. memcpy(pDest, bufferData, length);
  79. unlock();
  80. }
  81. void GLBuffer::writeData(UINT32 offset, UINT32 length,
  82. const void* pSource, BufferWriteType writeFlags)
  83. {
  84. GpuLockOptions lockOption = GBL_WRITE_ONLY;
  85. if (writeFlags == BWT_DISCARD)
  86. lockOption = GBL_WRITE_ONLY_DISCARD;
  87. else if (writeFlags == BTW_NO_OVERWRITE)
  88. lockOption = GBL_WRITE_ONLY_NO_OVERWRITE;
  89. void* bufferData = lock(offset, length, lockOption);
  90. memcpy(bufferData, pSource, length);
  91. unlock();
  92. }
  93. void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length)
  94. {
  95. glBindBuffer(GL_COPY_READ_BUFFER, getGLBufferId());
  96. glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
  97. glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
  98. }
  99. }}