| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #ifndef ANKI_GL_BUFFER_OBJECT_H
- #define ANKI_GL_BUFFER_OBJECT_H
- #include "anki/gl/Ogl.h"
- #include "anki/util/Assert.h"
- #include "anki/util/StdTypes.h"
- namespace anki {
- /// @addtogroup gl
- /// @{
-
- /// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
- /// to prevent us from making idiotic errors
- class BufferObject
- {
- public:
- /// @name Constructors/Destructor
- /// @{
- BufferObject()
- {}
- /// @see create
- BufferObject(GLenum target, U32 sizeInBytes,
- const void* dataPtr, GLenum usage)
- {
- create(target, sizeInBytes, dataPtr, usage);
- }
- /// It deletes the BO from the GL context
- ~BufferObject();
- /// @}
- /// @name Accessors
- /// @{
- GLuint getGlId() const
- {
- ANKI_ASSERT(isCreated());
- return glId;
- }
- GLenum getBufferTarget() const
- {
- ANKI_ASSERT(isCreated());
- return target;
- }
- GLenum getBufferUsage() const
- {
- ANKI_ASSERT(isCreated());
- return usage;
- }
- U32 getSizeInBytes() const
- {
- ANKI_ASSERT(isCreated());
- return sizeInBytes;
- }
- /// @]
- /// Bind BO
- void bind() const
- {
- ANKI_ASSERT(isCreated());
- //if(lastBindedBo != this)
- {
- glBindBuffer(target, glId);
- //lastBindedBo = this;
- }
- }
- /// Unbind BO
- void unbind() const
- {
- ANKI_ASSERT(isCreated());
- glBindBuffer(target, 0);
- //lastBindedBo = nullptr;
- }
- /// Creates a new BO with the given parameters and checks if everything
- /// went OK. Throws exception if fails
- /// @param target Depends on the BO
- /// @param sizeInBytes The size of the buffer that we will allocate in bytes
- /// @param dataPtr Points to the data buffer to copy to the VGA memory.
- /// Put NULL if you want just to allocate memory
- /// @param usage It should be: GL_STREAM_DRAW or GL_STATIC_DRAW or
- /// GL_DYNAMIC_DRAW only!!!!!!!!!
- /// @exception Exception
- void create(GLenum target, U32 sizeInBytes, const void* dataPtr,
- GLenum usage);
- /// Delete the BO
- void destroy()
- {
- ANKI_ASSERT(isCreated());
- unbind();
- glDeleteBuffers(1, &glId);
- glId = 0;
- }
- /// Write data to buffer. This means that maps the BO to local memory,
- /// writes the local memory and unmaps it. Throws exception if the
- /// given size and the BO size are not equal. It throws an exception if
- /// the usage is GL_STATIC_DRAW
- /// @param[in] buff The buffer to copy to BO
- void write(void* buff);
- /// The same as the other write but it maps only a subset of the data
- /// @param[in] buff The buffer to copy to BO
- /// @param[in] offset The offset
- /// @param[in] size The size in bytes we want to write
- void write(void* buff, U32 offset, U32 size);
- /// Map buffer
- void* map(U32 offset, U32 length, GLuint flags);
- /// Map the entire buffer
- void* map(GLuint flags)
- {
- return map(0, sizeInBytes, flags);
- }
- /// Unmap buffer
- void unmap();
- /// If created is run successfully this returns true
- bool isCreated() const
- {
- return glId != 0;
- }
- void setBinding(GLuint binding) const
- {
- ANKI_ASSERT(target == GL_TRANSFORM_FEEDBACK_BUFFER
- || target == GL_UNIFORM_BUFFER);
- bind();
- glBindBufferBase(target, binding, glId);
- }
- private:
- /// Opt to save a few glBindBuffer calls
- static const thread_local BufferObject* lastBindedBo;
- GLuint glId = 0; ///< The OpenGL id of the BO
- /// Used in glBindBuffer(target, glId) and its for easy access so we
- /// wont have to query the GL driver. Its the type of the buffer eg
- /// GL_TEXTURE_BUFFER or GL_ELEMENT_ARRAY_BUFFER etc
- GLenum target;
- GLenum usage; ///< GL_STREAM_DRAW or GL_STATIC_DRAW or GL_DYNAMIC_DRAW
- U32 sizeInBytes; ///< The size of the buffer
- #if !NDEBUG
- Bool mapped = false;
- #endif
- };
- /// @}
- } // end namespace anki
- #endif
|