yupplemayham/YuppleMayham/include/graphics/sprite.h

117 lines
No EOL
2.6 KiB
C++

#ifndef _H_SPRITE_H
#define _H_SPRITE_H
#include <SDL_image.h>
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <vector>
#include <unordered_map>
#include <memory>
#include "utility/direction.h"
enum class TileType;
class Texture;
class EventManager;
class Sprite
{
public:
virtual ~Sprite() {}
void bind();
virtual void draw() = 0;
bool loaded() const;
virtual std::shared_ptr<Sprite> clone() const = 0;
protected:
Texture* texture = nullptr;
unsigned indices[6] = {
0, 1, 2,
3, 2, 0
};
};
class SpriteStatic : public Sprite
{
public:
SpriteStatic(const char* texturePath);
~SpriteStatic();
void draw() override;
std::shared_ptr<Sprite> clone() const override {
return std::make_shared<SpriteStatic>(*this);
}
private:
void setupSprite();
// Vertex Array, Vertex Buffer, Element Buffer
unsigned VAO, VBO, EBO;
// simple rectangle. Most scales will be done based on this generic vertex data.
float vertices[20] = {
// vertex texturecoords
0.0f, 0.0f, 0.0f, 0.0f, 0.0f, // bottom left
1.0f, 0.0f, 0.0f, 1.0f, 0.0f, // bottom right
1.0f, 1.0f, 0.0f, 1.0f, 1.0f, // top right
0.0f, 1.0f, 0.0f, 0.0f, 1.0f // top left
};
};
class SpriteAtlas : public Sprite
{
public:
struct VertexIDs {
unsigned VAO, VBO;
};
// let's keep texture grids squares, saves everyone time...
SpriteAtlas(const char* textureAtlasPath, float frameSize, bool isDirectional = false);
~SpriteAtlas();
void bindFrame(VertexIDs* f);
// draw current frame
void draw() override;
VertexIDs frame(int index, Direction dir = Direction::None) {
if (dir == Direction::None) return singleFrame(index);
return dirFrames(dir, index);
}
size_t size() { return (isDirectional) ? directionalIDs.size() : singleIDs.size(); }
std::shared_ptr<Sprite> clone() const override {
return std::make_shared<SpriteAtlas>(*this);
}
private:
void Setup(float frameSize);
void SetupDirectional(float frameSize);
unsigned EBO;
bool isDirectional;
VertexIDs* curFrame;
VertexIDs singleFrame(int index) const {
return (index < 0 || index >= singleIDs.size()) ? singleIDs[0] : singleIDs[index];
}
// return the frame in the direction at the selected index
VertexIDs dirFrames(Direction dir, int index) const {
return (index < 0 || index >= directionalIDs.at(dir).size()) ? directionalIDs.at(dir)[0] : directionalIDs.at(dir)[index];
}
// Vertex array buffer IDs, if the sprite atlas is non-directional
std::vector<VertexIDs> singleIDs;
// Vertex ids if the sprite atlas is directional
std::unordered_map<Direction, std::vector<VertexIDs>> directionalIDs;
};
#endif // _H_SPRITE_H