#ifndef _H_SPRITE_H #define _H_SPRITE_H #include #include #include #include #include #include #include #include "utility/direction.h" enum class TileType; class Texture; class EventManager; class UnitQuad; 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(); UnitQuad* quad; }; 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(); // bind the frame VAO before drawing 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 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