/* +------------------------------------------------------+ ____/ \____ /| - Open source game framework licensed to freely use, | \ / / | copy, modify and sell without restriction | +--\ ^__^ /--+ | | | ~/ \~ | | - created for | | ~~~~~~~~~~~~ | +------------------------------------------------------+ | SPACE ~~~~~ | / | ~~~~~~~ BOX |/ +-------------*/ #pragma once /* GL functions */ #if defined(__EMSCRIPTEN__) #include #elif defined(__ANDROID__) || defined(ANDROID) #include #include #else #include "glew/glew.h" #endif #include #include #include #include #include #include #include "glm/glm.hpp" #include "Attributes.hpp" #include "Texture.hpp" #include "Carousel.hpp" namespace sb { class Model { private: inline static const std::string DEFAULT_TEXTURE_NAME = "default"; std::map _textures; std::map> _attributes; glm::mat4 _transformation {1.0f}; public: Model(); Model(const std::map>&); Model(const std::map&); Model(const std::initializer_list&); std::map>& attributes(); std::shared_ptr& attributes(const std::string&); void attributes(const sb::Attributes&, const std::string&); void attributes(const std::shared_ptr&, const std::string&); std::shared_ptr& operator[](const std::string&); void enable(); void disable(); std::map& textures(); sb::Texture& texture(const std::string&); sb::Texture& texture(); void texture(const sb::Texture&, const std::string&); void texture(const sb::Texture&); /*! * @return a constanst reference to the model's transformation matrix */ const glm::mat4& transformation() const; /*! * Apply the given transformation matrix to the model's current transformation matrix. * * @return the model's new transformation matrix */ const glm::mat4& transform(const glm::mat4& transformation); /*! * Resets the model's transformation to the identity matrix. * * @return the model's new transformation matrix, the identity matrix */ const glm::mat4& untransform(); /*! * Specialized version of transform(const glm::mat4&) that builds a scale transformation from an x, y, z vector and * applies it to the model's transformation matrix. * * @param scale x, y, z scale * @return the model's new transformation matrix */ const glm::mat4& scale(const glm::vec3& scale); /*! * Scale all dimensions by the same amount. * @overload scale(const glm::vec3&) */ const glm::mat4& scale(float scale); /*! * Specialized version of transform(const glm::mat4&) that builds a rotation matrix from an angle in radians and an axis * vector and applies it to the model's transformation matrix. * * The axis is the vector around which the model will be rotated. For example, to rotate a 2D plane around the origin, use * the z-axis: `glm::vec3(0.0f, 0.0f, 1.0f)`. * * @param angle angle in radians * @param axis axis to rotate the model around * @return the model's new transformation matrix */ const glm::mat4& rotate(float angle, glm::vec3 axis); /*! * Specialized version of transform(const glm::mat4&) that builds a translation matrix from a 3D translation vector * indicating the distance to translate along each axis and applies it to the model's transformation matrix. * * @param translation distance to translate in the x, y, and z dimensions * @return the model's new transformation matrix */ const glm::mat4& translate(glm::vec3 translation); std::size_t size(); operator glm::mat4() const; }; class Plane : public Model { public: /* A plane in the X and Y dimensions, from (-1.0, -1.0) to (1.0, 1.0) */ inline const static std::shared_ptr position = std::make_shared(sb::Attributes{ {-1.0f, 1.0f}, {1.0f, 1.0f}, {-1.0f, -1.0f}, {1.0f, 1.0f}, {1.0f, -1.0f}, {-1.0f, -1.0f} }); /* Map a texture to fill the plane */ inline const static std::shared_ptr uv = std::make_shared(sb::Attributes{ {0.0f, 1.0f}, {1.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 1.0f}, {1.0f, 0.0f}, {0.0f, 0.0f} }); /* A gradient from magenta to yellow */ inline const static std::shared_ptr color = std::make_shared(sb::Attributes{ {1.0f, 1.0f, 0.0f, 1.0f}, {1.0f, 1.0f, 0.0f, 1.0f}, {0.8f, 0.0f, 0.3f, 1.0f}, {1.0f, 1.0f, 0.0f, 1.0f}, {0.8f, 0.0f, 0.3f, 1.0f}, {0.8f, 0.0f, 0.3f, 1.0f} }); Plane() : Model(std::map>({{"position", position}, {"uv", uv}, {"color", color}})) {} }; /*! * A version of `Plane` which contains two texture objects, one of which is active at a time. A reference * to the active `sb::Texture` object is available from `PlaneDoubleBuffer.active`, and the inactive object is * available from `PlaneDoubleBuffer.inactive`. The buffers can be swapped using `PlaneDoubleBuffer.swap`. */ class PlaneDoubleBuffer : public Plane { private: bool swapped = false; public: PlaneDoubleBuffer(); void generate(const glm::vec2&); sb::Texture& active(); sb::Texture& inactive(); void swap(); }; }