|
|
@@ -10,10 +10,10 @@ namespace anki {
|
|
|
|
|
|
/// A wrapper for OpenGL buffer objects (vertex arrays, texture buffers etc)
|
|
|
/// to prevent us from making idiotic errors
|
|
|
-class BufferObject: public GlObject
|
|
|
+class BufferObject: public GlMultiObject
|
|
|
{
|
|
|
public:
|
|
|
- typedef GlObject Base;
|
|
|
+ typedef GlMultiObject Base;
|
|
|
|
|
|
/// @name Constructors/Destructor
|
|
|
/// @{
|
|
|
@@ -28,13 +28,6 @@ public:
|
|
|
*this = std::move(b);
|
|
|
}
|
|
|
|
|
|
- /// @see create
|
|
|
- BufferObject(GLenum target, U32 sizeInBytes,
|
|
|
- const void* dataPtr, GLenum usage)
|
|
|
- {
|
|
|
- create(target, sizeInBytes, dataPtr, usage);
|
|
|
- }
|
|
|
-
|
|
|
/// It deletes the BO
|
|
|
~BufferObject()
|
|
|
{
|
|
|
@@ -76,15 +69,7 @@ public:
|
|
|
void bind() const
|
|
|
{
|
|
|
ANKI_ASSERT(isCreated());
|
|
|
- glBindBuffer(target, glId);
|
|
|
- }
|
|
|
-
|
|
|
- /// Bind and change target
|
|
|
- void bind(GLenum target_)
|
|
|
- {
|
|
|
- ANKI_ASSERT(isCreated());
|
|
|
- setTarget(target_);
|
|
|
- glBindBuffer(target, glId);
|
|
|
+ glBindBuffer(target, glId[getGlobTimestamp() % objectsCount]);
|
|
|
}
|
|
|
|
|
|
/// Unbind BO
|
|
|
@@ -102,9 +87,9 @@ public:
|
|
|
/// 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
|
|
|
+ /// @param objectCount The number of objects
|
|
|
void create(GLenum target, U32 sizeInBytes, const void* dataPtr,
|
|
|
- GLenum usage);
|
|
|
+ GLenum usage, U objectCount = SINGLE_OBJECT);
|
|
|
|
|
|
/// Delete the BO
|
|
|
void destroy();
|
|
|
@@ -151,38 +136,10 @@ public:
|
|
|
void unmap();
|
|
|
|
|
|
/// Set the binding for this buffer
|
|
|
- void setBinding(GLuint binding) const
|
|
|
- {
|
|
|
- Bool correctTarget = target == GL_TRANSFORM_FEEDBACK_BUFFER
|
|
|
-#if ANKI_GL == ANKI_GL_DESKTOP
|
|
|
- || target == GL_SHADER_STORAGE_BUFFER
|
|
|
-#endif
|
|
|
- || target == GL_UNIFORM_BUFFER;
|
|
|
-
|
|
|
- ANKI_ASSERT(correctTarget);
|
|
|
- (void)correctTarget;
|
|
|
-
|
|
|
- glBindBufferBase(target, binding, glId);
|
|
|
- }
|
|
|
+ void setBinding(GLuint binding) const;
|
|
|
|
|
|
/// Set the binding point of this buffer with range
|
|
|
- void setBindingRange(GLuint binding, PtrSize offset, PtrSize size) const
|
|
|
- {
|
|
|
- Bool correctTarget = target == GL_TRANSFORM_FEEDBACK_BUFFER
|
|
|
-#if ANKI_GL == ANKI_GL_DESKTOP
|
|
|
- || target == GL_SHADER_STORAGE_BUFFER
|
|
|
-#endif
|
|
|
- || target == GL_UNIFORM_BUFFER;
|
|
|
-
|
|
|
- ANKI_ASSERT(correctTarget);
|
|
|
- (void)correctTarget;
|
|
|
-
|
|
|
- ANKI_ASSERT(offset + size <= sizeInBytes);
|
|
|
- ANKI_ASSERT(size > 0);
|
|
|
-
|
|
|
- glBindBufferRange(target, binding, glId, offset, size);
|
|
|
- ANKI_CHECK_GL_ERROR();
|
|
|
- }
|
|
|
+ void setBindingRange(GLuint binding, PtrSize offset, PtrSize size) const;
|
|
|
|
|
|
/// Return GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT
|
|
|
static PtrSize getUniformBufferOffsetAlignment()
|
|
|
@@ -205,6 +162,67 @@ private:
|
|
|
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)
|
|
|
+ {
|
|
|
+ GLint64 maxBufferSize;
|
|
|
+ glGetInteger64v(GL_MAX_UNIFORM_BLOCK_SIZE, &maxBufferSize);
|
|
|
+ ANKI_ASSERT(size <= (PtrSize)maxBufferSize);
|
|
|
+
|
|
|
+ BufferObject::create(GL_UNIFORM_BUFFER, size, data, GL_DYNAMIC_DRAW,
|
|
|
+ objectCount);
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+/// 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
|