#ifndef _H_SPRITE_H #define _H_SPRITE_H #include #include #include #include #include #include #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 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 clone() const override { return std::make_shared(*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 clone() const override { return std::make_shared(*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 singleIDs; // Vertex ids if the sprite atlas is directional std::unordered_map> directionalIDs; }; #endif // _H_SPRITE_H