spacebox/src/VBO.hpp

107 lines
4.2 KiB
C++

/* /\ +--------------------------------------------------------------+
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
\ / / | copy, modify and sell without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - originally created at [http://nugget.fun] |
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+--------------+
[VBO.hpp]
This class can be used to allocate space for vertex attributes on the GPU and transfer their
values into the allocated space.
First allocate space by passing a size in bytes to the allocate member function. This size
can be calculated by adding together the sizes of every Attributes object that is intended to
be added to the VBO. After allocating, pass each Attributes object to the add function one at
a time to fill the buffer.
This class doesn't support updating the attribute values once they've been added. To do that,
either reallocate the entire buffer and re-add the attribute values or keep track of the offset
returned by the add function and use glBufferSubData independently.
*/
#pragma once
#include <iostream>
#include <sstream>
#include "GLObject.hpp"
#include "Attributes.hpp"
#include "Log.hpp"
namespace sb
{
class VBO;
std::ostream& operator<<(std::ostream&, const VBO&);
class VBO : public Buffer
{
private:
GLintptr offset = 0;
public:
/*!
* Construct a Vertex Buffer Object object. The base GLObject will be constructed with a target of `GL_ARRAY_BUFFER`.
*/
VBO();
/*!
* Generate an ID for VBO using the base class's generate function. Reset the offset to 0 because any data previously stored will be
* automatically freed once a new ID is generated.
*/
void generate();
/*!
* Allocate size bytes of unintialized vertex buffer memory on the GPU.
*
* Usage should be one of GL_STREAM_DRAW, GL_STREAM_READ, GL_STREAM_COPY, GL_STATIC_DRAW, GL_STATIC_READ, GL_STATIC_COPY, GL_DYNAMIC_DRAW,
* GL_DYNAMIC_READ, or GL_DYNAMIC_COPY. If using `glBufferSubData` directly to change the VBO's data frequently, a value other than the
* default GL_STATIC_DRAW can be used.
*
* The VBO must currently be bound.
*
* @param size number of bytes of GPU memory to allocate to the buffer
* @param usage indicator to the GL implementation of how the data will be used, see `glBufferData` for info
*/
void allocate(GLsizeiptr size, GLenum usage = GL_STATIC_DRAW);
/*!
* Set memory in the GPU buffer to the values of the attribute data using `glBufferSubData`. The memory is a contiguous area from the
* object's current byte offset value to the offset plus the size in bytes of the attributes. After the memory is set, the offset is
* updated to point to the end of the area.
*
* The offset replaces the currently set offset in the sb::Attributes object, so the attributes object can associate its vertex data with
* the VAO by passing the offset along when it calls `glVertexAttribPointer` in its sb::Attributes::bind() method.
*
* The VBO must currently be bound.
*
* @warning This function is expected to change in the future to allow more control over the offset so
* the VBO can be refilled using this class.
*
* @param attributes vertices to be added to the vertex buffer, wrapped in a sb::Attributes object
* @return the new offset that indicates the end of the vertex buffer
*/
GLintptr add(sb::Attributes&);
/*!
* Stream a string representation containing the ID# to the output stream.
*
* @param out output stream
* @param vbo this object's string representation will be passed to the stream
* @return the edited stream
*/
friend std::ostream& operator<<(std::ostream& out, const VBO& vbo);
};
}