Merge pull request #86 from AnonymusRaccoon/renderer

model now use shared ptr + cache system to spare memory
This commit is contained in:
Arthi-chaud
2021-06-01 14:09:53 +02:00
committed by GitHub
17 changed files with 155 additions and 69 deletions
+1
View File
@@ -6,6 +6,7 @@
*/
#include "Drawables/2D/Circle.hpp"
#include "Drawables/Image.hpp"
namespace RAY::Drawables::Drawables2D
{
+1
View File
@@ -7,6 +7,7 @@
#include "Drawables/2D/Line.hpp"
#include <cmath>
#include "Drawables/Image.hpp"
namespace RAY::Drawables::Drawables2D
{
+1
View File
@@ -6,6 +6,7 @@
*/
#include "Drawables/2D/Point.hpp"
#include "Drawables/Image.hpp"
namespace RAY::Drawables::Drawables2D
{
@@ -7,6 +7,7 @@
#include "Drawables/2D/Rectangle.hpp"
#include <cmath>
#include "Drawables/Image.hpp"
namespace RAY::Drawables::Drawables2D
{
@@ -48,4 +49,15 @@ namespace RAY::Drawables::Drawables2D
{
ImageDrawRectangleV(image, this->_position, this->_dimensions, this->_color);
}
Rectangle::operator ::Rectangle() const
{
::Rectangle rect;
rect.x = this->_position.x;
rect.y = this->_position.y;
rect.width = this->_dimensions.x;
rect.height = this->_dimensions.y;
return rect;
}
}
+9 -6
View File
@@ -20,7 +20,7 @@ namespace RAY::Drawables::Drawables2D {
//! @param position position of top-left point
//! @param dimensions dimensions of the rectangle
//! @param Color Color of the rectangle
Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color);
Rectangle(const Vector2 &position, const Vector2 &dimensions, const Color &color = WHITE);
//! @brief Rectangle constructor
//! @param x x-position of top-left point
@@ -28,7 +28,7 @@ namespace RAY::Drawables::Drawables2D {
//! @param width width of the rectangle
//! @param length length of the rectangle
//! @param Color Color of the rectangle
Rectangle(int x, int y, int width, int height, const Color &color);
Rectangle(int x, int y, int width, int height, const Color &color = WHITE);
//! @brief A default copy constructor
Rectangle(const Rectangle &) = default;
@@ -37,7 +37,7 @@ namespace RAY::Drawables::Drawables2D {
Rectangle &operator=(const Rectangle &) = default;
//! @brief A default destructor
~Rectangle() override = default;
virtual ~Rectangle() override = default;
//! @return the dimensions of the rectangle
const Vector2 &getDimensions(void);
@@ -49,13 +49,16 @@ namespace RAY::Drawables::Drawables2D {
Rectangle &setDimensions(int x, int y);
//! @brief Draw point on window
void drawOn(RAY::Window &) override;
virtual void drawOn(RAY::Window &) override;
//! @brief Draw point on image
void drawOn(RAY::Image &image) override;
virtual void drawOn(RAY::Image &image) override;
private:
protected:
//! @brief Diemnsions of the rectangle
Vector2 _dimensions;
INTERNAL:
operator ::Rectangle() const;
};
};
+1 -1
View File
@@ -6,7 +6,7 @@
*/
#include "Drawables/2D/Text.hpp"
#include "Drawables/Image.hpp"
#include <utility>
namespace RAY::Drawables::Drawables2D
@@ -7,6 +7,7 @@
#include "Drawables/2D/Triangle.hpp"
#include "Exceptions/RayError.hpp"
#include "Drawables/Image.hpp"
namespace RAY::Drawables::Drawables2D
{
@@ -6,6 +6,7 @@
*/
#include "Drawables/ADrawable2D.hpp"
#include "Image.hpp"
namespace RAY::Drawables
{
+3 -1
View File
@@ -10,10 +10,12 @@
#include <raylib.h>
#include "Vector/Vector2.hpp"
#include "Image.hpp"
#include "Drawables/IDrawable.hpp"
#include "Color.hpp"
namespace RAY {
class Image;
}
namespace RAY::Drawables {
//! @brief Abstraction of any two-dimensionnal drawable
class ADrawable2D: public IDrawable
+57 -25
View File
@@ -6,36 +6,68 @@
*/
#include "Drawables/Image.hpp"
#include "Drawables/IDrawable.hpp"
#include "Drawables/ADrawable2D.hpp"
#include "Drawables/2D/Rectangle.hpp"
RAY::Image::Image(const std::string &filename):
_image(LoadImage(filename.c_str()))
{
}
namespace RAY {
std::unordered_map<std::string, std::shared_ptr<::Image>> Image::_ImageCache;
RAY::Image::Image(RAY::Texture &texture):
_image(GetTextureData(texture))
{
Image::Image(const std::string &filename):
Rectangle(Vector2(0, 0), Vector2(0, 0), WHITE),
_image(fetchImageInCache(filename))
{
this->_dimensions = Vector2(this->_image->width, this->_image->height);
}
}
bool Image::exportTo(const std::string &outputPath)
{
ExportImage(*this->_image, outputPath.c_str());
return true;
}
RAY::Image::~Image()
{
UnloadImage(_image);
}
Image::operator ::Image() const
{
return *this->_image;
}
bool RAY::Image::exportTo(const std::string &outputPath)
{
ExportImage(_image, outputPath.c_str());
return true;
}
Image::operator ::Image *()
{
return this->_image.get();
}
RAY::Image::operator ::Image() const
{
return _image;
}
std::shared_ptr<::Image> Image::fetchImageInCache(const std::string &path)
{
if (Image::_ImageCache.find(path) == Image::_ImageCache.end())
Image::_ImageCache.emplace(path, std::shared_ptr<::Image>(
new ::Image(LoadImage(path.c_str())), [](::Image *p) {
UnloadImage(*p);
delete p;
}));
return _ImageCache[path];
}
RAY::Image::operator ::Image *()
{
return &this->_image;
void Image::draw(Drawables::ADrawable2D &drawable)
{
drawable.drawOn(*this);
}
void Image::drawOn(RAY::Window &)
{
//Since the image is a shared object, when it is resized, it mush be resized after to its previous dimensions
Vector2 oldDims = Vector2(this->_image->width, this->_image->height);
ImageResize(*this, this->_dimensions.x, this->_dimensions.y);
Texture texture(*this);
DrawTexture(texture, this->_position.x, this->_position.y, this->_color);
ImageResize(*this, oldDims.x, oldDims.y);
}
void Image::drawOn(RAY::Image &image)
{
Drawables::Drawables2D::Rectangle dest(this->_position, this->getDimensions());
Drawables::Drawables2D::Rectangle src(Vector2(0, 0), this->getDimensions());
ImageDraw(image, *this, dest, src, this->_color);
}
}
+21 -14
View File
@@ -11,43 +11,50 @@
#include <raylib.h>
#include <string>
#include "Texture.hpp"
#include <memory>
#include <unordered_map>
#include "Drawables/2D/Rectangle.hpp"
namespace RAY
{
namespace Drawables {
class ADrawable2D;
}
//! @brief Object representation of a framebuffer
class Image {
class Image: public Drawables::Drawables2D::Rectangle {
public:
//! @brief Create an image, loading a file
//! @param filename: path to file to load
Image(const std::string &filename);
//! @brief Create an image, using data from a texure
//! @param texture: texture to extract data from
Image(Texture &texture);
//! @brief A default copy constructor
Image(const Image &image) = delete;
Image(const Image &image) = default;
//! @brief An image is assignable
Image &operator=(const Image &image) = delete;
Image &operator=(const Image &image) = default;
//! @brief Image destructor, will unload ressources
~Image();
~Image() override = default;
//! @brief export to file
//! @param outputPath: path of output
bool exportTo(const std::string &outputPath);
//! @brief draw drawable
//! @brief draw drawable on image
void draw(Drawables::ADrawable2D &);
//! @brief Draw image on window
void drawOn(RAY::Window &) override;
//! @brief Draw image on another image
void drawOn(RAY::Image &image) override;
private:
//! @brief Image, really, that's just it...
::Image _image;
std::shared_ptr<::Image> _image;
//! @brief, look through cache to see if a model using same file
std::shared_ptr<::Image>fetchImageInCache(const std::string &path);
static std::unordered_map<std::string, std::shared_ptr<::Image>> _ImageCache;
INTERNAL:
//! @brief get image
+6
View File
@@ -21,6 +21,12 @@ namespace RAY {
{
}
Texture::Texture(const Image &image):
_texture(LoadTextureFromImage(image)),
_resourcePath()
{
}
Texture &Texture::operator=(const Texture &other)
{
+5 -2
View File
@@ -20,10 +20,13 @@ namespace RAY
//! @param filename: path to file to load
Texture(const std::string &filename);
//! @brief A texture is not copy constructable
//! @brief A texture is copy constructable
Texture(const Texture &);
//! @brief An image is assignable
//! @brief A textrue can be loaded from an image
Texture(const Image &);
//! @brief An texture is assignable
Texture &operator=(const Texture &);
//! @brief Texture destructor, will unload ressources
+24 -14
View File
@@ -7,9 +7,12 @@
#include "Model/Model.hpp"
#include "Exceptions/RayError.hpp"
#include <unordered_map>
namespace RAY::Drawables::Drawables3D {
std::unordered_map<std::string, std::shared_ptr<::Model>> Model::_modelsCache;
Model::Model(const std::string &filename,
std::optional<std::pair<MaterialType, std::string>> texture,
const RAY::Vector3 &position,
@@ -17,7 +20,7 @@ namespace RAY::Drawables::Drawables3D {
float rotationAngle,
const RAY::Vector3 &scale)
: ADrawable3D(position, WHITE),
_model(LoadModel(filename.c_str())),
_model(fetchModelInCache(filename)),
_rotationAxis(rotationAxis),
_rotationAngle(rotationAngle),
_scale(scale)
@@ -27,33 +30,29 @@ namespace RAY::Drawables::Drawables3D {
}
Model::Model(const Mesh &mesh)
: ADrawable3D({0, 0, 0}, WHITE), _model(LoadModelFromMesh(mesh))
: ADrawable3D({0, 0, 0}, WHITE),
_model(std::make_shared<::Model>(LoadModelFromMesh(mesh)))
{
}
Model::~Model()
{
UnloadModel(this->_model);
}
bool Model::unloadKeepMeshes()
{
UnloadModelKeepMeshes(_model);
UnloadModelKeepMeshes(*this->_model);
return true;
}
bool Model::setAnimation(const RAY::ModelAnimation &animation)
{
if (!IsModelAnimationValid(this->_model, animation))
if (!IsModelAnimationValid(*this->_model, animation))
throw RAY::Exception::NotCompatibleError("The animation is not compatible with the model");
UpdateModelAnimation(this->_model, animation, animation.getFrameCounter());
UpdateModelAnimation(*this->_model, animation, animation.getFrameCounter());
return true;
}
bool Model::setTextureToMaterial(Model::MaterialType materialType, const std::string &texturePath)
{
this->_textureList.emplace(materialType, texturePath);
SetMaterialTexture(&this->_model.materials[materialType],
SetMaterialTexture(&this->_model->materials[materialType],
materialType,
this->_textureList.at(materialType));
return true;
@@ -61,12 +60,12 @@ namespace RAY::Drawables::Drawables3D {
Model::operator ::Model() const
{
return this->_model;
return *this->_model;
}
int Model::getBoneCount() const
{
return this->_model.boneCount;
return this->_model->boneCount;
}
Model &Model::setRotationAngle(float rotationAngle)
@@ -104,6 +103,17 @@ namespace RAY::Drawables::Drawables3D {
void Model::drawOn(RAY::Window &)
{
DrawModelEx(this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color);
DrawModelEx(*this->_model, this->_position, this->_rotationAxis, this->_rotationAngle, this->_scale, this->_color);
}
std::shared_ptr<::Model> Model::fetchModelInCache(const std::string &path)
{
if (Model::_modelsCache.find(path) == Model::_modelsCache.end())
Model::_modelsCache.emplace(path, std::shared_ptr<::Model>(
new ::Model(LoadModel(path.c_str())), [](::Model *p) {
UnloadModel(*p);
delete p;
}));
return _modelsCache[path];
}
}
+10 -5
View File
@@ -14,7 +14,8 @@
#include <raylib.h>
#include <vector>
#include <optional>
#include <map>
#include <unordered_map>
#include <memory>
namespace RAY::Drawables::Drawables3D {
//! @brief Basic 3D Model type
@@ -42,8 +43,8 @@ namespace RAY::Drawables::Drawables3D {
//! @brief A model is assignable
Model& operator=(const Model &model) = default;
//! @brief Model destructor, unloads all related data
~Model();
//! @brief Model destructor, model's data will be deleted if it's the last entity alive
~Model() override = default;
//! @brief Unload model (excluding meshes) from memory (RAM and/or VRAM)
bool unloadKeepMeshes();
@@ -81,15 +82,19 @@ namespace RAY::Drawables::Drawables3D {
private:
//! @brief Raw data from raylib
::Model _model;
std::shared_ptr<::Model> _model;
//! @brief The list of textures that can be applied to this model.
std::map<MaterialType, Texture> _textureList;
std::unordered_map<MaterialType, Texture> _textureList;
//! @brief Rotation property
RAY::Vector3 _rotationAxis;
//! @brief Rotation property
float _rotationAngle;
//! @brief Scale of the shape
RAY::Vector3 _scale;
//! @brief, look through cache to see if a model using same file
std::shared_ptr<::Model>fetchModelInCache(const std::string &path);
static std::unordered_map<std::string, std::shared_ptr<::Model>> _modelsCache;
INTERNAL:
//! @brief A RAY Model is cast-able in libray's model
+1
View File
@@ -11,6 +11,7 @@
#include "Controllers/Mouse.hpp"
#include "Drawables/ADrawable2D.hpp"
#include "Drawables/ADrawable3D.hpp"
#include "Drawables/Image.hpp"
std::optional<RAY::Window> RAY::Window::_instance = std::nullopt;
+1 -1
View File
@@ -11,7 +11,6 @@
#include <raylib.h>
#include <string>
#include <optional>
#include "Drawables/Image.hpp"
#include "Vector/Vector2.hpp"
#include "Vector/Vector3.hpp"
#include "Controllers/Keyboard.hpp"
@@ -22,6 +21,7 @@
namespace RAY {
//! @brief Window manager
class Image;
namespace Drawables {
class IDrawable;
class ADrawable3D;