| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- #ifndef ANKI_GL_BUFFER_OBJECT_H
- #define ANKI_GL_BUFFER_OBJECT_H
- #include "anki/gl/GlObject.h"
- namespace anki {
- /// @addtogroup OpenGL
- /// @{
-
- /// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
- /// to prevent us from making idiotic errors
- class BufferObject: public GlObject
- {
- public:
- typedef GlObject Base;
- /// @name Constructors/Destructor
- /// @{
- /// Default
- BufferObject()
- {}
- /// Move
- BufferObject(BufferObject&& b)
- {
- *this = std::move(b);
- }
- /// It deletes the BO
- ~BufferObject()
- {
- destroy();
- }
- /// @}
- /// Move
- BufferObject& operator=(BufferObject&& b);
- /// @name Accessors
- /// @{
- GLenum getTarget() const
- {
- ANKI_ASSERT(isCreated());
- return target;
- }
- void setTarget(GLenum target_)
- {
- ANKI_ASSERT(isCreated());
- target = target_;
- }
- GLenum getUsage() const
- {
- ANKI_ASSERT(isCreated());
- return usage;
- }
- U32 getSizeInBytes() const
- {
- ANKI_ASSERT(isCreated());
- return sizeInBytes;
- }
- /// @}
- /// Bind
- void bind() const
- {
- ANKI_ASSERT(isCreated());
- glBindBuffer(target, getGlId());
- }
- /// Unbind BO
- void unbind() const
- {
- ANKI_ASSERT(isCreated());
- glBindBuffer(target, 0);
- }
- /// 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!!!!!!!!!
- /// @param objectCount The number of objects
- void create(GLenum target, U32 sizeInBytes, const void* dataPtr,
- GLenum usage, U objectCount = SINGLE_OBJECT);
- /// Delete the BO
- void destroy();
- /// 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)
- {
- write(buff, 0, sizeInBytes);
- }
- /// 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);
- /// Read the containts of the buffer
- /// @param[out] outBuff The buffer to copy from BO
- void read(void* outBuff)
- {
- read(outBuff, 0, sizeInBytes);
- }
- /// Read the containts of the buffer
- /// @param[in] outBuff The buffer to copy from BO
- /// @param[in] offset The offset
- /// @param[in] size The size in bytes we want to write
- void read(void* buff, U32 offset, U32 size);
- /// Map part of the 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();
- /// Set the binding for this buffer
- void setBinding(GLuint binding) const;
- /// Set the binding point of this buffer with range
- void setBindingRange(GLuint binding, PtrSize offset, PtrSize size) const;
- /// Return GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
- static PtrSize getUniformBufferOffsetAlignment()
- {
- GLint64 offsetAlignment;
- glGetInteger64v(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &offsetAlignment);
- return offsetAlignment;
- }
- private:
- /// 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 ANKI_DEBUG
- Bool mapped = false; ///< Only in debug
- #endif
- };
- /// This is a wrapper for Vertex Buffer Objects to prevent us from making
- /// idiotic errors
- class Vbo: public BufferObject
- {
- public:
- /// The same as BufferObject::create but it only accepts
- /// GL_ARRAY_BUFFER or GL_ELEMENT_ARRAY_BUFFER in target
- /// @see BufferObject::create
- void create(GLenum target, PtrSize sizeInBytes, const void* dataPtr,
- GLenum usage, U objectCount = SINGLE_OBJECT)
- {
- // unacceptable target_
- ANKI_ASSERT(target == GL_ARRAY_BUFFER
- || target == GL_ELEMENT_ARRAY_BUFFER);
- BufferObject::create(target, sizeInBytes, dataPtr, usage, objectCount);
- }
- /// Unbinds all VBOs, meaning both GL_ARRAY_BUFFER and
- /// GL_ELEMENT_ARRAY_BUFFER targets
- static void unbindAllTargets()
- {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- }
- };
- /// Uniform buffer object
- class Ubo: public BufferObject
- {
- public:
- /// Create a UBO
- void create(PtrSize size, const void* data, U objectCount = SINGLE_OBJECT);
- };
- /// Pixel buffer object
- class Pbo: public BufferObject
- {
- public:
- /// Create a PBO
- void create(GLenum target, PtrSize size, const void* data,
- U objectCount = SINGLE_OBJECT)
- {
- ANKI_ASSERT(target == GL_PIXEL_PACK_BUFFER
- || target == GL_PIXEL_UNPACK_BUFFER);
- GLenum pboUsage = (target == GL_PIXEL_PACK_BUFFER)
- ? GL_DYNAMIC_READ : GL_DYNAMIC_DRAW;
- BufferObject::create(target, size, data, pboUsage, objectCount);
- }
- };
- /// @}
- } // end namespace anki
- #endif
|