abstract base class for GL objects
This commit is contained in:
parent
1a4b8507e3
commit
6adac9806f
|
@ -50,7 +50,7 @@ CFLAGS := -Wall -O0 -c -I$(SB_LIB_DIR) -I$(SB_SRC_DIR) $(shell $(SDLCONFIG) --cf
|
|||
CPP_FLAGS := $(CFLAGS) --std=c++17
|
||||
LFLAGS := $(shell $(SDLCONFIG) --libs) -lpthread
|
||||
SB_H_FILES := $(wildcard $(addprefix $(SB_SRC_DIR),*.hpp))
|
||||
SB_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o),$(SB_H_FILES:.hpp=.o))
|
||||
SB_O_FILES := $(filter-out $(addprefix $(SB_SRC_DIR),filesystem.o GLObject.o),$(SB_H_FILES:.hpp=.o))
|
||||
SRC_H_FILES := $(wildcard $(addprefix $(SRC_DIR),*.hpp))
|
||||
SRC_O_FILES := $(SRC_H_FILES:.hpp=.o)
|
||||
|
||||
|
@ -77,6 +77,7 @@ $(SB_SRC_DIR)Box.o : $(addprefix $(SB_SRC_DIR),extension.hpp Segment.hpp)
|
|||
$(SB_SRC_DIR)Segment.o : $(addprefix $(SB_SRC_DIR),extension.hpp Box.hpp)
|
||||
$(SB_SRC_DIR)Pixels.o : $(addprefix $(SB_SRC_DIR),Box.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)Audio.o : $(addprefix $(SB_SRC_DIR),Node.hpp Display.hpp Configuration.hpp Box.hpp filesystem.hpp extension.hpp)
|
||||
$(SB_SRC_DIR)Texture.o : $(addprefix $(SB_SRC_DIR),GLObject.hpp)
|
||||
$(SRC_DIR)Squircle.o : $(SB_H_FILES)
|
||||
%.o : %.cpp %.hpp
|
||||
$(CPPC) $(CPP_FLAGS) $< -c -o $@
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
#include "GLObject.hpp"
|
||||
|
||||
/* A deleter function is required for freeing the memory allocated to the object (this could be, for example,
|
||||
* glDeleteTextures for a Texture object, or a custom function that does something in addition to calling
|
||||
* the appropriate GL deleter function) */
|
||||
GLObject::GLObject(std::function<void(GLuint*)> deleter)
|
||||
{
|
||||
this->deleter = deleter;
|
||||
}
|
||||
|
||||
/* Set the shared pointer to point to a new GLuint with specified ID value */
|
||||
void GLObject::id(GLuint id)
|
||||
{
|
||||
/* The deleter will be called when the object and all of its copies have gone out of scope */
|
||||
object_id = std::shared_ptr<GLuint>(new GLuint, deleter);
|
||||
*object_id = id;
|
||||
}
|
||||
|
||||
/* Return the GL ID that was set for this object */
|
||||
GLuint GLObject::id() const
|
||||
{
|
||||
return *object_id;
|
||||
}
|
||||
|
||||
/* Returns true if an ID has been generated */
|
||||
bool GLObject::generated() const
|
||||
{
|
||||
return static_cast<bool>(object_id);
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
/* /\ +--------------------------------------------------------------+
|
||||
____/ \____ /| - zlib/MIT/Unlicenced game framework licensed to freely use, |
|
||||
\ / / | copy, modify and sell without restriction |
|
||||
+--\ ^__^ /--+ | |
|
||||
| ~/ \~ | | - originally created at [http://nugget.fun] |
|
||||
| ~~~~~~~~~~~~ | +--------------------------------------------------------------+
|
||||
| SPACE ~~~~~ | /
|
||||
| ~~~~~~~ BOX |/
|
||||
+--------------+
|
||||
|
||||
[GLObject.hpp]
|
||||
|
||||
The abstract GLObject class is meant to be inherited by specific types of OpenGL objects,
|
||||
for example Textures or Buffer objects. It stores the object's ID and declares virtual
|
||||
functions for generating, binding, and destroying the object.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef GLObject_h_
|
||||
#define GLObject_h_
|
||||
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
/* include Open GL */
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <GL/glew.h>
|
||||
#else
|
||||
#include "glew/glew.h"
|
||||
#endif
|
||||
|
||||
class GLObject
|
||||
{
|
||||
|
||||
protected:
|
||||
|
||||
std::shared_ptr<GLuint> object_id = nullptr;
|
||||
std::function<void(GLuint*)> deleter = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
GLObject(std::function<void(GLuint*)>);
|
||||
virtual void generate() = 0;
|
||||
virtual void bind() const = 0;
|
||||
void id(GLuint);
|
||||
GLuint id() const;
|
||||
bool generated() const;
|
||||
virtual ~GLObject() = default;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -35,9 +35,11 @@
|
|||
#include "filesystem.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
struct FramerateIndicator : Sprite
|
||||
class FramerateIndicator : public Sprite
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
FramerateIndicator(Node*);
|
||||
void respond(SDL_Event&);
|
||||
SDL_Surface* get_surface();
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include "Color.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
struct Sprite;
|
||||
class Sprite;
|
||||
|
||||
struct Pixels
|
||||
{
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "glm/vec2.hpp"
|
||||
|
||||
class Box;
|
||||
struct Sprite;
|
||||
class Sprite;
|
||||
|
||||
class Segment
|
||||
{
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "Game.hpp"
|
||||
#include "Sprite.hpp"
|
||||
|
||||
Sprite::Sprite() : Sprite(nullptr) {}
|
||||
|
@ -115,12 +116,12 @@ const std::vector<SDL_Texture*>& Sprite::get_frames() const
|
|||
return frames;
|
||||
}
|
||||
|
||||
Frameset& Sprite::get_all_frames_frameset()
|
||||
Sprite::Frameset& Sprite::get_all_frames_frameset()
|
||||
{
|
||||
return framesets[get_configuration()["animation"]["all-frames-frameset-name"]];
|
||||
}
|
||||
|
||||
Frameset& Sprite::add_frameset(std::string name)
|
||||
Sprite::Frameset& Sprite::add_frameset(std::string name)
|
||||
{
|
||||
if (framesets.find(name) == framesets.end())
|
||||
{
|
||||
|
@ -129,7 +130,7 @@ Frameset& Sprite::add_frameset(std::string name)
|
|||
return framesets[name];
|
||||
}
|
||||
|
||||
Frameset& Sprite::set_frameset(std::string name)
|
||||
Sprite::Frameset& Sprite::set_frameset(std::string name)
|
||||
{
|
||||
current_frameset_name = name;
|
||||
frame_animation.set_frame_length(get_current_frameset().get_frame_length());
|
||||
|
@ -140,12 +141,12 @@ Frameset& Sprite::set_frameset(std::string name)
|
|||
return get_current_frameset();
|
||||
}
|
||||
|
||||
Frameset& Sprite::get_current_frameset()
|
||||
Sprite::Frameset& Sprite::get_current_frameset()
|
||||
{
|
||||
return framesets.at(current_frameset_name);
|
||||
}
|
||||
|
||||
const Frameset& Sprite::get_current_frameset() const
|
||||
const Sprite::Frameset& Sprite::get_current_frameset() const
|
||||
{
|
||||
return framesets.at(current_frameset_name);
|
||||
}
|
||||
|
@ -933,17 +934,17 @@ void Sprite::set_to_deallocate_memory()
|
|||
leave_memory_allocated = false;
|
||||
}
|
||||
|
||||
Frameset::Frameset() : Frameset(NULL) {}
|
||||
Sprite::Frameset::Frameset() : Frameset(NULL) {}
|
||||
|
||||
Frameset::Frameset(Sprite* sprite) : sprite(sprite) {}
|
||||
Sprite::Frameset::Frameset(Sprite* sprite) : sprite(sprite) {}
|
||||
|
||||
void Frameset::add_frame_indicies(int index)
|
||||
void Sprite::Frameset::add_frame_indicies(int index)
|
||||
{
|
||||
order.push_back(index);
|
||||
set_size();
|
||||
}
|
||||
|
||||
void Frameset::set_frame_length(float length)
|
||||
void Sprite::Frameset::set_frame_length(float length)
|
||||
{
|
||||
frame_length = length;
|
||||
if (&sprite->get_current_frameset() == this)
|
||||
|
@ -952,38 +953,38 @@ void Frameset::set_frame_length(float length)
|
|||
}
|
||||
}
|
||||
|
||||
float Frameset::get_frame_length() const
|
||||
float Sprite::Frameset::get_frame_length() const
|
||||
{
|
||||
return frame_length;
|
||||
}
|
||||
|
||||
void Frameset::reset()
|
||||
void Sprite::Frameset::reset()
|
||||
{
|
||||
set_order_index(0);
|
||||
}
|
||||
|
||||
void Frameset::clear()
|
||||
void Sprite::Frameset::clear()
|
||||
{
|
||||
order.clear();
|
||||
reset();
|
||||
}
|
||||
|
||||
int Frameset::get_order_index() const
|
||||
int Sprite::Frameset::get_order_index() const
|
||||
{
|
||||
return order_index;
|
||||
}
|
||||
|
||||
void Frameset::set_order_index(int index)
|
||||
void Sprite::Frameset::set_order_index(int index)
|
||||
{
|
||||
order_index = index;
|
||||
}
|
||||
|
||||
int Frameset::get_current_frame_index() const
|
||||
int Sprite::Frameset::get_current_frame_index() const
|
||||
{
|
||||
return order[get_order_index()];
|
||||
}
|
||||
|
||||
glm::vec2 Frameset::measure() const
|
||||
glm::vec2 Sprite::Frameset::measure() const
|
||||
{
|
||||
glm::vec2 s(0, 0);
|
||||
int w, h;
|
||||
|
@ -999,22 +1000,22 @@ glm::vec2 Frameset::measure() const
|
|||
return s;
|
||||
}
|
||||
|
||||
void Frameset::set_size()
|
||||
void Sprite::Frameset::set_size()
|
||||
{
|
||||
set_size(measure());
|
||||
}
|
||||
|
||||
void Frameset::set_size(const glm::vec2& s)
|
||||
void Sprite::Frameset::set_size(const glm::vec2& s)
|
||||
{
|
||||
size = s;
|
||||
}
|
||||
|
||||
const glm::vec2& Frameset::get_size() const
|
||||
const glm::vec2& Sprite::Frameset::get_size() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
void Frameset::step()
|
||||
void Sprite::Frameset::step()
|
||||
{
|
||||
if (order.size() > 0)
|
||||
{
|
||||
|
@ -1022,22 +1023,22 @@ void Frameset::step()
|
|||
}
|
||||
}
|
||||
|
||||
void Frameset::increment_index()
|
||||
void Sprite::Frameset::increment_index()
|
||||
{
|
||||
increment_index(reversed ? -1 : 1);
|
||||
}
|
||||
|
||||
void Frameset::increment_index(int increment)
|
||||
void Sprite::Frameset::increment_index(int increment)
|
||||
{
|
||||
set_order_index((order_index + increment) % order.size());
|
||||
}
|
||||
|
||||
int Frameset::get_frame_count() const
|
||||
int Sprite::Frameset::get_frame_count() const
|
||||
{
|
||||
return order.size();
|
||||
}
|
||||
|
||||
void Frameset::reverse()
|
||||
void Sprite::Frameset::reverse()
|
||||
{
|
||||
reversed = !reversed;
|
||||
}
|
||||
|
|
|
@ -9,22 +9,23 @@
|
|||
#include <utility>
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
|
||||
#include "Node.hpp"
|
||||
#include "Box.hpp"
|
||||
#include "Animation.hpp"
|
||||
#include "Color.hpp"
|
||||
|
||||
class Game;
|
||||
struct Frameset;
|
||||
|
||||
struct Sprite : Node
|
||||
class Sprite : public Node
|
||||
{
|
||||
|
||||
struct Child;
|
||||
public:
|
||||
|
||||
class Frameset;
|
||||
class Child;
|
||||
|
||||
std::vector<SDL_Texture*> frames;
|
||||
std::vector<fs::path> frame_paths;
|
||||
std::vector<Box> boxes = {{{0, 0}, {0, 0}}};
|
||||
|
@ -145,12 +146,14 @@ struct Sprite : Node
|
|||
void set_to_leave_memory_allocated();
|
||||
void set_to_deallocate_memory();
|
||||
virtual std::string class_name() const { return "Sprite"; }
|
||||
~Sprite() { unload(); }
|
||||
|
||||
};
|
||||
|
||||
struct Sprite::Child
|
||||
class Sprite::Child
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
std::string name;
|
||||
Sprite sprite;
|
||||
|
||||
|
@ -160,11 +163,14 @@ struct Sprite::Child
|
|||
{
|
||||
return this->name == name;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Frameset
|
||||
class Sprite::Frameset
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Sprite* sprite;
|
||||
std::vector<int> order;
|
||||
int order_index = 0;
|
||||
|
@ -204,7 +210,6 @@ struct Frameset
|
|||
};
|
||||
|
||||
#include "Pixels.hpp"
|
||||
#include "Game.hpp"
|
||||
#include "extension.hpp"
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "Texture.hpp"
|
||||
|
||||
/* Have to pass our deleter to abstract base class at instantiation */
|
||||
Texture::Texture() : GLObject(texture_deleter) {}
|
||||
|
||||
/* If an image path is passed at creation, the path will be stored in the class for later loading */
|
||||
Texture::Texture(fs::path path)
|
||||
Texture::Texture(fs::path path) : Texture()
|
||||
{
|
||||
associate(path);
|
||||
}
|
||||
|
@ -13,12 +16,18 @@ void Texture::associate(fs::path path)
|
|||
this->path = path;
|
||||
}
|
||||
|
||||
/* Generate a GL_TEXTURE_2D texture and allocate GL_RGB8 storage for the given size */
|
||||
void Texture::generate(glm::vec2 size)
|
||||
/* Generate an ID for this Texture and save it */
|
||||
void Texture::generate()
|
||||
{
|
||||
GLuint id;
|
||||
glGenTextures(1, &id);
|
||||
this->id(id);
|
||||
}
|
||||
|
||||
/* Generate a GL_TEXTURE_2D texture ID and allocate GL_RGB8 storage for the given size */
|
||||
void Texture::generate(glm::vec2 size)
|
||||
{
|
||||
generate();
|
||||
bind();
|
||||
glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGB8, size.x, size.y);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
|
@ -26,12 +35,6 @@ void Texture::generate(glm::vec2 size)
|
|||
Game::log_gl_errors();
|
||||
}
|
||||
|
||||
/* Returns true if an ID has been generated for this Texture */
|
||||
bool Texture::generated() const
|
||||
{
|
||||
return static_cast<bool>(texture_id);
|
||||
}
|
||||
|
||||
/* When called with no parameters, use the stored path variable */
|
||||
void Texture::load()
|
||||
{
|
||||
|
@ -92,19 +95,6 @@ void Texture::load(void* pixels, GLenum format, GLenum type)
|
|||
}
|
||||
}
|
||||
|
||||
/* Set the shared pointer to point to a new GLuint with specified ID value */
|
||||
void Texture::id(GLuint id)
|
||||
{
|
||||
texture_id = std::shared_ptr<GLuint>(new GLuint, Texture::destroy);
|
||||
*texture_id = id;
|
||||
}
|
||||
|
||||
/* Return the GL texture ID that was set for this texture */
|
||||
GLuint Texture::id() const
|
||||
{
|
||||
return *texture_id;
|
||||
}
|
||||
|
||||
void Texture::bind() const
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, this->id());
|
||||
|
@ -129,16 +119,17 @@ glm::vec2 Texture::size() const
|
|||
}
|
||||
}
|
||||
|
||||
/* Delete this texture, freeing the memory */
|
||||
void Texture::destroy(GLuint* id)
|
||||
{
|
||||
/* not sure why SDL_Log works here but SDL_LogDebug and SDL_LogInfo don't */
|
||||
SDL_Log("destroying texture ID %i", *id);
|
||||
glDeleteTextures(1, id);
|
||||
}
|
||||
|
||||
/* Textures are considered equal if they have the same ID */
|
||||
bool Texture::operator==(const Texture& texture) const
|
||||
{
|
||||
return id() == texture.id();
|
||||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
/* 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);
|
||||
glDeleteTextures(1, id);
|
||||
}
|
||||
|
|
|
@ -20,12 +20,12 @@
|
|||
#ifndef Texture_h_
|
||||
#define Texture_h_
|
||||
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include "SDL.h"
|
||||
#include "SDL_image.h"
|
||||
#include "sdl2-gfx/SDL2_rotozoom.h"
|
||||
#include "filesystem.hpp"
|
||||
#include "GLObject.hpp"
|
||||
#include "Game.hpp"
|
||||
|
||||
/* include Open GL */
|
||||
|
@ -35,34 +35,32 @@
|
|||
#include "glew/glew.h"
|
||||
#endif
|
||||
|
||||
class Texture
|
||||
class Texture : public GLObject
|
||||
{
|
||||
|
||||
|
||||
private:
|
||||
|
||||
fs::path path = "";
|
||||
std::shared_ptr<GLuint> texture_id = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
Texture() {};
|
||||
Texture();
|
||||
Texture(fs::path);
|
||||
void associate(fs::path);
|
||||
void generate() override;
|
||||
void generate(glm::vec2);
|
||||
bool generated() const;
|
||||
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 id(GLuint);
|
||||
GLuint id() const;
|
||||
void bind() const;
|
||||
void bind() const override;
|
||||
glm::vec2 size() const;
|
||||
static void destroy(GLuint*);
|
||||
bool operator==(const Texture&) const;
|
||||
|
||||
};
|
||||
|
||||
void texture_deleter(GLuint*);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue