BsGLBuffer.cpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. {
  21. glDeleteBuffers(1, &mBufferId);
  22. BS_CHECK_GL_ERROR();
  23. }
  24. }
  25. void GLBuffer::initialize(GLenum target, UINT32 size, GpuBufferUsage usage)
  26. {
  27. assert(mBufferId == 0 && "Buffer already initialized");
  28. mTarget = target;
  29. glGenBuffers(1, &mBufferId);
  30. BS_CHECK_GL_ERROR();
  31. if (!mBufferId)
  32. BS_EXCEPT(InternalErrorException, "Cannot create GL buffer");
  33. glBindBuffer(target, mBufferId);
  34. BS_CHECK_GL_ERROR();
  35. glBufferData(target, size, nullptr, GLHardwareBufferManager::getGLUsage(usage));
  36. BS_CHECK_GL_ERROR();
  37. }
  38. void* GLBuffer::lock(UINT32 offset, UINT32 length, GpuLockOptions options)
  39. {
  40. GLenum access = 0;
  41. glBindBuffer(mTarget, mBufferId);
  42. BS_CHECK_GL_ERROR();
  43. if ((options == GBL_WRITE_ONLY) || (options == GBL_WRITE_ONLY_NO_OVERWRITE) || (options == GBL_WRITE_ONLY_DISCARD))
  44. {
  45. access = GL_MAP_WRITE_BIT;
  46. if (options == GBL_WRITE_ONLY_DISCARD)
  47. access |= GL_MAP_INVALIDATE_BUFFER_BIT;
  48. else if (options == GBL_WRITE_ONLY_NO_OVERWRITE)
  49. access |= GL_MAP_UNSYNCHRONIZED_BIT;
  50. }
  51. else if (options == GBL_READ_ONLY)
  52. access = GL_MAP_READ_BIT;
  53. else
  54. access = GL_MAP_READ_BIT | GL_MAP_WRITE_BIT;
  55. void* buffer = nullptr;
  56. if (length > 0)
  57. {
  58. buffer = glMapBufferRange(mTarget, offset, length, access);
  59. BS_CHECK_GL_ERROR();
  60. if (buffer == nullptr)
  61. BS_EXCEPT(InternalErrorException, "Cannot map OpenGL buffer.");
  62. mZeroLocked = false;
  63. }
  64. else
  65. mZeroLocked = true;
  66. return static_cast<void*>(static_cast<unsigned char*>(buffer));
  67. }
  68. void GLBuffer::unlock()
  69. {
  70. glBindBuffer(mTarget, mBufferId);
  71. BS_CHECK_GL_ERROR();
  72. if (!mZeroLocked)
  73. {
  74. if (!glUnmapBuffer(mTarget))
  75. {
  76. BS_CHECK_GL_ERROR();
  77. BS_EXCEPT(InternalErrorException, "Buffer data corrupted, please reload.");
  78. }
  79. }
  80. }
  81. void GLBuffer::readData(UINT32 offset, UINT32 length, void* pDest)
  82. {
  83. void* bufferData = lock(offset, length, GBL_READ_ONLY);
  84. memcpy(pDest, bufferData, length);
  85. unlock();
  86. }
  87. void GLBuffer::writeData(UINT32 offset, UINT32 length,
  88. const void* pSource, BufferWriteType writeFlags)
  89. {
  90. GpuLockOptions lockOption = GBL_WRITE_ONLY;
  91. if (writeFlags == BWT_DISCARD)
  92. lockOption = GBL_WRITE_ONLY_DISCARD;
  93. else if (writeFlags == BTW_NO_OVERWRITE)
  94. lockOption = GBL_WRITE_ONLY_NO_OVERWRITE;
  95. void* bufferData = lock(offset, length, lockOption);
  96. memcpy(bufferData, pSource, length);
  97. unlock();
  98. }
  99. void GLBuffer::copyData(GLBuffer& dstBuffer, UINT32 srcOffset, UINT32 dstOffset, UINT32 length)
  100. {
  101. glBindBuffer(GL_COPY_READ_BUFFER, getGLBufferId());
  102. BS_CHECK_GL_ERROR();
  103. glBindBuffer(GL_COPY_WRITE_BUFFER, dstBuffer.getGLBufferId());
  104. BS_CHECK_GL_ERROR();
  105. glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, srcOffset, dstOffset, length);
  106. BS_CHECK_GL_ERROR();
  107. }
  108. }}