vbo, vao, and buffer classes
This commit is contained in:
parent
3e5e0fcbb8
commit
3212dc15cf
|
@ -11,6 +11,7 @@
|
|||
*/
|
||||
|
||||
#include "GLObject.hpp"
|
||||
using namespace sb;
|
||||
|
||||
/* The deleter function is used for freeing the memory allocated to the object (for example, glDeleteTextures,
|
||||
* or a custom function that does something in addition to calling the appropriate GL deleter function). */
|
||||
|
@ -48,3 +49,75 @@ bool GLObject::generated() const
|
|||
{
|
||||
return static_cast<bool>(object_id);
|
||||
};
|
||||
|
||||
VAO::VAO() : GLObject(vao_deleter) {}
|
||||
|
||||
/* Bind this VAO to the current GL context */
|
||||
void VAO::bind() const
|
||||
{
|
||||
glBindVertexArray(id());
|
||||
}
|
||||
|
||||
/* Forward the GL VAO generate function to the base class */
|
||||
void VAO::generate()
|
||||
{
|
||||
GLObject::generate(glGenVertexArrays);
|
||||
}
|
||||
|
||||
/* This function gets passed to the abstract base class for deleting the VAO data when the ID
|
||||
* pointer goes out of scope (when all instances of this VAO and its copies are out of scope) */
|
||||
void sb::vao_deleter(GLuint* id)
|
||||
{
|
||||
/* not sure why SDL_Log works here on program exit but SDL_LogDebug and SDL_LogInfo don't */
|
||||
SDL_Log("destroying VAO ID %i", *id);
|
||||
glDeleteVertexArrays(1, id);
|
||||
}
|
||||
|
||||
Buffer::Buffer() : Buffer(GL_INVALID_ENUM) {}
|
||||
|
||||
Buffer::Buffer(GLenum target) : GLObject(buffer_deleter), buffer_target(target) {}
|
||||
|
||||
/* Forward the GL generate function to the base class. */
|
||||
void Buffer::generate()
|
||||
{
|
||||
GLObject::generate(glGenBuffers);
|
||||
}
|
||||
|
||||
/* Set the target for this buffer. */
|
||||
void Buffer::target(GLenum target)
|
||||
{
|
||||
buffer_target = target;
|
||||
}
|
||||
|
||||
/* Return the GL enum for target */
|
||||
GLenum Buffer::target() const
|
||||
{
|
||||
return buffer_target;
|
||||
}
|
||||
|
||||
/* Bind this Buffer to the current GL context. An exception will be thrown if the target has not
|
||||
* been set. */
|
||||
void Buffer::bind() const
|
||||
{
|
||||
if (target() == GL_INVALID_ENUM)
|
||||
{
|
||||
throw std::invalid_argument("target must be set before binding buffer");
|
||||
}
|
||||
glBindBuffer(target(), id());
|
||||
}
|
||||
|
||||
/* Set the target and bind the buffer. */
|
||||
void Buffer::bind(GLenum target)
|
||||
{
|
||||
this->target(target);
|
||||
bind();
|
||||
}
|
||||
|
||||
/* This function gets passed to the abstract base class for deleting the Buffer data when the ID
|
||||
* pointer goes out of scope (when all instances of this Buffer and its copies are out of scope) */
|
||||
void sb::buffer_deleter(GLuint* id)
|
||||
{
|
||||
/* not sure why SDL_Log works here on program exit but SDL_LogDebug and SDL_LogInfo don't */
|
||||
SDL_Log("destroying buffer ID %i", *id);
|
||||
glDeleteBuffers(1, id);
|
||||
}
|
||||
|
|
|
@ -17,11 +17,17 @@
|
|||
An appropriate deleter function must be passed in to the constructor from the derived
|
||||
class. It can be a custom function, or it can be one of the GL deleter functions like
|
||||
glDeleteTextures.
|
||||
|
||||
A VAO class and a general Buffer class are also defined here. The VAO class just fills
|
||||
in the abstract methods of the GLObject class and doesn't have any further Space Box
|
||||
specific implementation. The buffer class is probably most useful being inherited by a
|
||||
derived class that implements a more specific type of buffer that passes its target to
|
||||
the base class, like the VBO class.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GLObject_h_
|
||||
#define GLObject_h_
|
||||
#ifndef SB_GLOBJECT_H_
|
||||
#define SB_GLOBJECT_H_
|
||||
|
||||
/* include Open GL */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
|
@ -36,30 +42,72 @@
|
|||
#include <functional>
|
||||
#include "Log.hpp"
|
||||
|
||||
class GLObject
|
||||
namespace sb
|
||||
{
|
||||
|
||||
private:
|
||||
class GLObject
|
||||
{
|
||||
|
||||
typedef std::function<void(GLsizei, GLuint*)> generator_function;
|
||||
typedef std::function<void(GLuint*)> deleter_function;
|
||||
private:
|
||||
|
||||
std::shared_ptr<GLuint> object_id = nullptr;
|
||||
deleter_function deleter = nullptr;
|
||||
typedef std::function<void(GLsizei, GLuint*)> generator_function;
|
||||
typedef std::function<void(GLuint*)> deleter_function;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<GLuint> object_id = nullptr;
|
||||
deleter_function deleter = nullptr;
|
||||
|
||||
GLObject(deleter_function);
|
||||
virtual void bind() const = 0;
|
||||
void generate(generator_function);
|
||||
protected:
|
||||
|
||||
public:
|
||||
GLObject(deleter_function);
|
||||
virtual void bind() const = 0;
|
||||
void generate(generator_function);
|
||||
|
||||
virtual void id(GLuint);
|
||||
virtual GLuint id() const;
|
||||
virtual bool generated() const;
|
||||
virtual ~GLObject() = default;
|
||||
public:
|
||||
|
||||
};
|
||||
virtual void id(GLuint);
|
||||
virtual GLuint id() const;
|
||||
virtual bool generated() const;
|
||||
virtual ~GLObject() = default;
|
||||
|
||||
};
|
||||
|
||||
class VAO : public GLObject
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
VAO();
|
||||
void generate();
|
||||
void bind() const;
|
||||
|
||||
};
|
||||
|
||||
void vao_deleter(GLuint*);
|
||||
|
||||
class Buffer : public GLObject
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
GLenum buffer_target = GL_INVALID_ENUM;
|
||||
|
||||
protected:
|
||||
|
||||
GLenum target() const;
|
||||
|
||||
public:
|
||||
|
||||
Buffer();
|
||||
Buffer(GLenum);
|
||||
void target(GLenum);
|
||||
void generate();
|
||||
void bind() const;
|
||||
void bind(GLenum);
|
||||
|
||||
};
|
||||
|
||||
void buffer_deleter(GLuint*);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,4 +1,17 @@
|
|||
/* /\ +--------------------------------------------------------------+
|
||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+--------------+
|
||||
|
||||
*/
|
||||
|
||||
#include "Texture.hpp"
|
||||
using namespace sb;
|
||||
|
||||
/* Have to pass our deleter to abstract base class at instantiation */
|
||||
Texture::Texture() : GLObject(texture_deleter) {}
|
||||
|
@ -125,7 +138,7 @@ bool Texture::operator==(const Texture& texture) const
|
|||
|
||||
/* This function gets passed to the abstract base class for deleting the texture data when the ID
|
||||
* pointer goes out of scope (when all instances of this texture and its copies are out of scope) */
|
||||
void texture_deleter(GLuint* id)
|
||||
void sb::texture_deleter(GLuint* id)
|
||||
{
|
||||
/* not sure why SDL_Log works here at program end but SDL_LogDebug and SDL_LogInfo don't */
|
||||
SDL_Log("destroying texture ID %i", *id);
|
||||
|
|
|
@ -19,9 +19,17 @@
|
|||
|
||||
*/
|
||||
|
||||
#ifndef Texture_h_
|
||||
#define Texture_h_
|
||||
#ifndef SB_TEXTURE_H_
|
||||
#define SB_TEXTURE_H_
|
||||
|
||||
/* include Open GL */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include "glew/glew.h"
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
#include "glm/vec2.hpp"
|
||||
#include "SDL.h"
|
||||
|
@ -31,39 +39,37 @@
|
|||
#include "GLObject.hpp"
|
||||
#include "Log.hpp"
|
||||
|
||||
/* include Open GL */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include "glew/glew.h"
|
||||
#endif
|
||||
|
||||
class Texture : public GLObject
|
||||
namespace sb
|
||||
{
|
||||
|
||||
class Texture : public GLObject
|
||||
{
|
||||
|
||||
private:
|
||||
private:
|
||||
|
||||
fs::path path = "";
|
||||
fs::path path = "";
|
||||
|
||||
public:
|
||||
public:
|
||||
|
||||
Texture();
|
||||
Texture(fs::path);
|
||||
void associate(fs::path);
|
||||
void generate();
|
||||
void generate(glm::vec2);
|
||||
void load();
|
||||
void load(fs::path);
|
||||
void load(SDL_RWops*);
|
||||
void load(SDL_Surface*);
|
||||
void load(void*, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||
void load(void*, glm::vec2, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||
void bind() const override;
|
||||
glm::vec2 size() const;
|
||||
bool operator==(const Texture&) const;
|
||||
Texture();
|
||||
Texture(fs::path);
|
||||
void associate(fs::path);
|
||||
void generate();
|
||||
void generate(glm::vec2);
|
||||
void load();
|
||||
void load(fs::path);
|
||||
void load(SDL_RWops*);
|
||||
void load(SDL_Surface*);
|
||||
void load(void*, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||
void load(void*, glm::vec2, GLenum = GL_RGBA, GLenum = GL_UNSIGNED_BYTE);
|
||||
void bind() const override;
|
||||
glm::vec2 size() const;
|
||||
bool operator==(const Texture&) const;
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
void texture_deleter(GLuint*);
|
||||
void texture_deleter(GLuint*);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/* /\ +--------------------------------------------------------------+
|
||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+--------------+
|
||||
|
||||
*/
|
||||
|
||||
#include "VBO.hpp"
|
||||
using namespace sb;
|
||||
|
||||
/* Initialize a Vertex Buffer Object. The base class will be initalized with a target of
|
||||
* GL_ARRAY_BUFFER. */
|
||||
VBO::VBO() : Buffer(GL_ARRAY_BUFFER) {}
|
||||
|
||||
/* Allocate size bytes of vertex attribute 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. The memory will be uninitialized. */
|
||||
void VBO::allocate(GLsizeiptr size, GLenum usage)
|
||||
{
|
||||
glBufferData(target(), size, nullptr, usage);
|
||||
/* Debug */
|
||||
std::ostringstream message;
|
||||
message << "After allocating memory for " << *this;
|
||||
sb::Log::gl_errors(message.str());
|
||||
}
|
||||
|
||||
/* Set memory in the GPU buffer to the values of the attribute data using glBufferSubData. The memory
|
||||
* set 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.
|
||||
*
|
||||
* Define an array of vertex attribute data on the GPU by passing the attributes's index, dimensions,
|
||||
* normalization state, and type to glVertexAttribPointer, along with the buffer object's current
|
||||
* offset.
|
||||
*
|
||||
* The updated offset is returned and can be used to independently keep track of where the next
|
||||
* attributes will be stored in the buffer and apply to direct usage of glBufferSubData. */
|
||||
GLintptr VBO::add(sb::Attributes& attributes)
|
||||
{
|
||||
/* Set memory */
|
||||
glBufferSubData(target(), offset, attributes.size(), attributes);
|
||||
/* Debug */
|
||||
std::ostringstream initialization_message;
|
||||
initialization_message << "After setting " << attributes.size() << "bytes in " << *this;
|
||||
sb::Log::gl_errors(initialization_message.str());
|
||||
/* Define array */
|
||||
glVertexAttribPointer(
|
||||
attributes.index(), attributes.dimensions(), attributes.type(), attributes.normalized(), 0, reinterpret_cast<GLvoid*>(offset));
|
||||
/* Debug */
|
||||
std::ostringstream pointer_message;
|
||||
pointer_message << "After defining attribute pointer for <Attributes (" << attributes.dimensions() << "D, id: " <<
|
||||
attributes.index() << ", size:" << attributes.size() << ")>";
|
||||
sb::Log::gl_errors(pointer_message.str());
|
||||
/* Increase offset */
|
||||
offset += attributes.size();
|
||||
return offset;
|
||||
}
|
||||
|
||||
/* Overload the stream operator to support the VBO string representation. */
|
||||
std::ostream& sb::operator<<(std::ostream& out, const VBO& vbo)
|
||||
{
|
||||
out << "<Vertex Buffer Object (id: " << vbo.id() << ")>";
|
||||
return out;
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/* /\ +--------------------------------------------------------------+
|
||||
____/ \____ /| - 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 readd the attribute values or keep track of the offset
|
||||
returned by the add function and use glBufferSubData independently.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef SB_VBO_H_
|
||||
#define SB_VBO_H_
|
||||
|
||||
/* include Open GL */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include "glew/glew.h"
|
||||
#endif
|
||||
|
||||
#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:
|
||||
|
||||
VBO();
|
||||
void allocate(GLsizeiptr, GLenum);
|
||||
GLintptr add(sb::Attributes&);
|
||||
friend std::ostream& operator<<(std::ostream&, const VBO&);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue