BufferObject.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. #ifndef ANKI_GL_BUFFER_OBJECT_H
  2. #define ANKI_GL_BUFFER_OBJECT_H
  3. #include "anki/gl/GlObject.h"
  4. namespace anki {
  5. /// @addtogroup OpenGL
  6. /// @{
  7. /// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
  8. /// to prevent us from making idiotic errors
  9. class BufferObject: public GlObject
  10. {
  11. public:
  12. typedef GlObject Base;
  13. /// @name Constructors/Destructor
  14. /// @{
  15. /// Default
  16. BufferObject()
  17. {}
  18. /// Move
  19. BufferObject(BufferObject&& b)
  20. {
  21. *this = std::move(b);
  22. }
  23. /// It deletes the BO
  24. ~BufferObject()
  25. {
  26. destroy();
  27. }
  28. /// @}
  29. /// Move
  30. BufferObject& operator=(BufferObject&& b);
  31. /// @name Accessors
  32. /// @{
  33. GLenum getTarget() const
  34. {
  35. ANKI_ASSERT(isCreated());
  36. return target;
  37. }
  38. void setTarget(GLenum target_)
  39. {
  40. ANKI_ASSERT(isCreated());
  41. target = target_;
  42. }
  43. GLenum getUsage() const
  44. {
  45. ANKI_ASSERT(isCreated());
  46. return usage;
  47. }
  48. U32 getSizeInBytes() const
  49. {
  50. ANKI_ASSERT(isCreated());
  51. return sizeInBytes;
  52. }
  53. /// @}
  54. /// Bind
  55. void bind() const
  56. {
  57. ANKI_ASSERT(isCreated());
  58. glBindBuffer(target, getGlId());
  59. }
  60. /// Unbind BO
  61. void unbind() const
  62. {
  63. ANKI_ASSERT(isCreated());
  64. glBindBuffer(target, 0);
  65. }
  66. /// Creates a new BO with the given parameters and checks if everything
  67. /// went OK. Throws exception if fails
  68. /// @param target Depends on the BO
  69. /// @param sizeInBytes The size of the buffer that we will allocate in bytes
  70. /// @param dataPtr Points to the data buffer to copy to the VGA memory.
  71. /// Put NULL if you want just to allocate memory
  72. /// @param usage It should be: GL_STREAM_DRAW or GL_STATIC_DRAW or
  73. /// GL_DYNAMIC_DRAW only!!!!!!!!!
  74. /// @param objectCount The number of objects
  75. void create(GLenum target, U32 sizeInBytes, const void* dataPtr,
  76. GLenum usage, U objectCount = SINGLE_OBJECT);
  77. /// Delete the BO
  78. void destroy();
  79. /// Write data to buffer. This means that maps the BO to local memory,
  80. /// writes the local memory and unmaps it. Throws exception if the
  81. /// given size and the BO size are not equal. It throws an exception if
  82. /// the usage is GL_STATIC_DRAW
  83. /// @param[in] buff The buffer to copy to BO
  84. void write(void* buff)
  85. {
  86. write(buff, 0, sizeInBytes);
  87. }
  88. /// The same as the other write but it maps only a subset of the data
  89. /// @param[in] buff The buffer to copy to BO
  90. /// @param[in] offset The offset
  91. /// @param[in] size The size in bytes we want to write
  92. void write(void* buff, U32 offset, U32 size);
  93. /// Read the containts of the buffer
  94. /// @param[out] outBuff The buffer to copy from BO
  95. void read(void* outBuff)
  96. {
  97. read(outBuff, 0, sizeInBytes);
  98. }
  99. /// Read the containts of the buffer
  100. /// @param[in] outBuff The buffer to copy from BO
  101. /// @param[in] offset The offset
  102. /// @param[in] size The size in bytes we want to write
  103. void read(void* buff, U32 offset, U32 size);
  104. /// Map part of the buffer
  105. void* map(U32 offset, U32 length, GLuint flags);
  106. /// Map the entire buffer
  107. void* map(GLuint flags)
  108. {
  109. return map(0, sizeInBytes, flags);
  110. }
  111. /// Unmap buffer
  112. void unmap();
  113. /// Set the binding for this buffer
  114. void setBinding(GLuint binding) const;
  115. /// Set the binding point of this buffer with range
  116. void setBindingRange(GLuint binding, PtrSize offset, PtrSize size) const;
  117. /// Return GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
  118. static PtrSize getUniformBufferOffsetAlignment()
  119. {
  120. GLint64 offsetAlignment;
  121. glGetInteger64v(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
  122. return offsetAlignment;
  123. }
  124. private:
  125. /// Used in glBindBuffer(target, glId) and its for easy access so we
  126. /// wont have to query the GL driver. Its the type of the buffer eg
  127. /// GL_TEXTURE_BUFFER or GL_ELEMENT_ARRAY_BUFFER etc
  128. GLenum target;
  129. GLenum usage; ///< GL_STREAM_DRAW or GL_STATIC_DRAW or GL_DYNAMIC_DRAW
  130. U32 sizeInBytes; ///< The size of the buffer
  131. #if ANKI_DEBUG
  132. Bool mapped = false; ///< Only in debug
  133. #endif
  134. };
  135. /// This is a wrapper for Vertex Buffer Objects to prevent us from making
  136. /// idiotic errors
  137. class Vbo: public BufferObject
  138. {
  139. public:
  140. /// The same as BufferObject::create but it only accepts
  141. /// GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER in target
  142. /// @see BufferObject::create
  143. void create(GLenum target, PtrSize sizeInBytes, const void* dataPtr,
  144. GLenum usage, U objectCount = SINGLE_OBJECT)
  145. {
  146. // unacceptable target_
  147. ANKI_ASSERT(target == GL_ARRAY_BUFFER
  148. || target == GL_ELEMENT_ARRAY_BUFFER);
  149. BufferObject::create(target, sizeInBytes, dataPtr, usage, objectCount);
  150. }
  151. /// Unbinds all VBOs, meaning both GL_ARRAY_BUFFER and
  152. /// GL_ELEMENT_ARRAY_BUFFER targets
  153. static void unbindAllTargets()
  154. {
  155. glBindBuffer(GL_ARRAY_BUFFER, 0);
  156. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  157. }
  158. };
  159. /// Uniform buffer object
  160. class Ubo: public BufferObject
  161. {
  162. public:
  163. /// Create a UBO
  164. void create(PtrSize size, const void* data, U objectCount = SINGLE_OBJECT);
  165. };
  166. /// Pixel buffer object
  167. class Pbo: public BufferObject
  168. {
  169. public:
  170. /// Create a PBO
  171. void create(GLenum target, PtrSize size, const void* data,
  172. U objectCount = SINGLE_OBJECT)
  173. {
  174. ANKI_ASSERT(target == GL_PIXEL_PACK_BUFFER
  175. || target == GL_PIXEL_UNPACK_BUFFER);
  176. GLenum pboUsage = (target == GL_PIXEL_PACK_BUFFER)
  177. ? GL_DYNAMIC_READ : GL_DYNAMIC_DRAW;
  178. BufferObject::create(target, size, data, pboUsage, objectCount);
  179. }
  180. };
  181. /// @}
  182. } // end namespace anki
  183. #endif