Skip to content
Snippets Groups Projects
Commit cd24aa25 authored by BATON Theau's avatar BATON Theau
Browse files

Add Sprite + Open to add custom graphic object

parent f9ada3d1
No related branches found
No related tags found
No related merge requests found
Showing
with 286 additions and 136 deletions
assets/textures/Image_Test.png

1.36 KiB

......@@ -4,12 +4,12 @@
namespace megu {
GraphicEngine::GraphicEngine(Window & window, float w, float h)
: _window(window), _view(0, 0, w, h) {
: _window(window) {
glViewport(0, 0, window.width(), window.height());
}
GraphicEngine::GraphicEngine(Window & window)
: _window(window), _view(0, 0, window.width(), window.height()) {
: _window(window) {
glViewport(0, 0, window.width(), window.height());
}
......@@ -17,10 +17,6 @@ namespace megu {
this->_layers[priority] = std::make_unique<Layer>(renderer);
}
//void GraphicEngine::push(Priority layer_priority, Priority object_priority, GraphicObject & object) {
// this->_layers[layer_priority].get()->push(object_priority, object);
//}
void GraphicEngine::remove(Priority priority) {
auto it = this->_layers.find(priority);
if(it != this->_layers.end()) {
......@@ -48,10 +44,7 @@ namespace megu {
// Merge Textures
FrameBuffer::BindDefaultFrameBuffer();
glViewport(0, 0, static_cast<GLsizei>(this->_window.width()), static_cast<GLsizei>(this->_window.height()));
glClear(GL_COLOR_BUFFER_BIT);
std::any any = 1;
this->_module.render(textures);
this->_merger.render(this->_window, textures);
this->_window.swapBuffers();
}
}
......
......@@ -3,7 +3,7 @@
#include <map>
#include <optional>
#include <engine/graphics/front/module/FrameBufferModule.hpp>
#include <engine/graphics/front/module/FrameBufferMerger.hpp>
#include <engine/graphics/back/cameras/View.hpp>
#include "Layer.hpp"
......@@ -19,8 +19,8 @@ namespace megu {
void push(Priority, Renderer &);
template <class T>
void push(Priority layer_priority, Priority object_priority, T & object) {
this->_layers[layer_priority].get()->push<T>(object_priority, object);
void push(Priority layer_priority, Priority object_priority, T & object, Module<T> * modul) {
this->_layers[layer_priority].get()->push<T>(object_priority, object, modul);
}
void remove(Priority);
......@@ -35,9 +35,7 @@ namespace megu {
private:
std::map<Priority, std::unique_ptr<Layer>> _layers;
FrameBufferModule _module;
FrameBufferMerger _merger;
Window & _window;
View _view;
};
}
\ No newline at end of file
......@@ -10,7 +10,7 @@
#include <engine/graphics/utility/reference_sorter.hpp>
#include <engine/graphics/front/object/Renderable.hpp>
#include <engine/graphics/front/module/QuadGraphicModule.hpp>
#include <engine/graphics/front/module/Module.hpp>
#include "Priority.hpp"
#include "Renderer.hpp"
......@@ -26,12 +26,13 @@ namespace megu {
inline const Renderer & renderer() const {return this->_renderer;}
template <class T>
void push(Priority priority, T & object) {
this->_objects.insert({priority, Renderable(object, this->_module)});
void push(Priority priority, T & object, Module<T> * modul) {
this->_objects.insert({priority, Renderable{ object, modul }});
}
const Texture & draw(const Window & w, const TextureArray & a) {
this->_frameBuffer.bind();
this->_renderer.clear();
for(auto & [type, object] : this->_objects) {
this->_renderer.render(w, object, a);
}
......@@ -40,9 +41,8 @@ namespace megu {
}
private:
Renderer & _renderer;
FrameBuffer _frameBuffer;
QuadGraphicModule _module;
Renderer & _renderer;
std::map<Priority, Renderable> _objects;
};
}
\ No newline at end of file
......@@ -7,11 +7,15 @@ namespace megu {
glEnable(GL_BLEND);
}
void Renderer::setClearColor(float r, float g, float b, float a) const {
glClearColor(r, g, b, a);
}
void Renderer::clear() const {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
void Renderer::setClearColor(float r, float g, float b, float a) const {
glClearColor(r, g, b, a);
void Renderer::render(const Window & w, Renderable & r, const TextureArray & a) {
render_ext(r, w, this->_view, a);
}
}
\ No newline at end of file
......@@ -13,21 +13,25 @@
#include <engine/graphics/front/object/Renderable.hpp>
namespace megu {
class Renderer {
class Producer {
public:
template <class T>
static Renderable produce(T & object, Module<T> & modul) {
return Renderable{object, modul};
}
};
class Renderer : public Producer {
public:
Renderer() = delete;
Renderer(float, float);
~Renderer() = default;
void render(const Window & w, Renderable & r, const TextureArray & a) {
this->clear();
render_ext(r, w, this->_view, a);
}
const glm::vec2 dimension() const {return this->_view.dimension();}
void clear() const;
void setClearColor(float, float, float, float = 1.f) const;
void render(const Window &, Renderable &, const TextureArray &);
View & view() {return this->_view;}
......
#include "FrameBufferModule.hpp"
#include "FrameBufferMerger.hpp"
#include <engine/graphics/front/geometry/Plane.hpp>
#include <engine/graphics/utility/array_generator.hpp>
namespace megu {
FrameBufferModule::FrameBufferModule()
FrameBufferMerger::FrameBufferMerger()
: _vbo(this->_vao, Plane::Layout(), Plane::Vertices(), megu::EditMode::STATIC) {
megu::Source vert("assets/shaders/FrameBuffer-Instanced.vert", Source::Categorie::VERTEX);
this->_program.attach(vert);
......@@ -18,7 +18,10 @@ namespace megu {
frag.release();
}
void FrameBufferModule::render(const TextureArray & textures) {
void FrameBufferMerger::render(const Window & window, const TextureArray & textures) {
glViewport(0, 0, static_cast<GLsizei>(window.width()), static_cast<GLsizei>(window.height()));
glClear(GL_COLOR_BUFFER_BIT);
this->_program.use();
this->_vao.bind();
......
......@@ -7,16 +7,17 @@
#include <engine/graphics/back/shaders/Program.hpp>
#include <engine/graphics/front/object/Image.hpp>
#include <engine/graphics/front/engine/Renderer.hpp>
#include "Module.hpp"
namespace megu {
class FrameBufferModule {
class FrameBufferMerger {
public:
FrameBufferModule();
~FrameBufferModule() = default;
FrameBufferMerger();
~FrameBufferMerger() = default;
void render(const TextureArray &);
void render(const Window &, const TextureArray &);
private:
VertexArray _vao;
......
......@@ -5,6 +5,8 @@
#include <engine/graphics/utility/reference_sorter.hpp>
#include <engine/io/Window.hpp>
#include <engine/graphics/utility/ref_set.hpp>
namespace megu {
template <class T>
class Module {
......@@ -12,15 +14,6 @@ namespace megu {
virtual void draw(T &, const Window &, const Camera &, const TextureArray &) const = 0;
};
template <class ... Ts>
class Multy_Module : public Module<Ts> ... {};
template <class T>
using ref_set = std::set<std::reference_wrapper<T>, reference_sorter<T>>;
template <class T>
using Module_Array = Module<ref_set<T>>;
template <class ... Ts>
class Multy_Module_Array : public Module_Array<Ts> ... {};
using Instanced_Module = Module<ref_set<T>>;
}
\ No newline at end of file
#include "QuadGraphicModule.hpp"
#include <engine/graphics/front/object/Image.hpp>
#include <engine/graphics/front/object/Sprite.hpp>
#include <iostream>
namespace megu {
void QuadGraphicModule::draw(Image &, const Window &, const Camera &, const TextureArray &) const {
std::cout << "Image !" << std::endl;
}
void QuadGraphicModule::draw(Sprite &, const Window &, const Camera &, const TextureArray &) const {
std::cout << "Sprite !" << std::endl;
}
}
\ No newline at end of file
#pragma once
#include "Module.hpp"
namespace megu {
class Image;
class Sprite;
class QuadGraphicModule : public Module<Image>, public Module<Sprite> {
public:
void draw(Image &, const Window &, const Camera &, const TextureArray &) const override;
void draw(Sprite &, const Window &, const Camera &, const TextureArray &) const override;
};
}
\ No newline at end of file
#include "QuadInstanced.hpp"
#include <engine/graphics/front/object/Image.hpp>
#include <engine/graphics/front/object/Sprite.hpp>
#include <engine/graphics/utility/array_generator.hpp>
#include <iostream>
namespace megu {
QuadInstancedModule::QuadInstancedModule()
: _vbo(this->_vao, Quads::Layout(), Quads::Vertices().size(), megu::EditMode::STATIC) {
{
Source vert("assets/shaders/Image-Instanced-Fat.vert", Source::Categorie::VERTEX);
this->_imageProgram.attach(vert);
Source frag("assets/shaders/Texture-Fat.frag", Source::Categorie::FRAGMENT);
this->_imageProgram.attach(frag);
this->_imageProgram.link();
vert.release();
frag.release();
}
{
Source vert("assets/shaders/Sprite.vert", Source::Categorie::VERTEX);
this->_spriteProgram.attach(vert);
Source frag("assets/shaders/Sprite.frag", Source::Categorie::FRAGMENT);
this->_spriteProgram.attach(frag);
this->_spriteProgram.link();
vert.release();
frag.release();
}
this->_vbo << Quads::Vertices();
}
void QuadInstancedModule::draw(ref_set<Image> & images, const Window & window, const Camera & camera, const TextureArray &) const {
this->_vao.bind();
this->_imageProgram.use();
this->_imageProgram.setUniform("uProj", camera.projection());
this->_imageProgram.setUniform("uView", camera.view());
std::vector<std::reference_wrapper<const Texture>> textures;
std::vector<glm::mat4> uModels;
std::vector<GLint> uTextures;
static auto uSampler = array_generator<GLint, 32>().array;
this->_imageProgram.setUniform("uSampler", uSampler);
for(auto & image : images) {
std::vector<std::reference_wrapper<const Texture>>::iterator it = std::find(textures.begin(), textures.end(), image.get().texture());
if(it != textures.end()) {
uModels.push_back(image.get().transformation().model());
uTextures.push_back(static_cast<GLint>(it - textures.begin()));
}
else {
if(textures.size() >= 8 || uModels.size() >= 124) {
this->_imageProgram.setUniform("uModel", uModels);
this->_imageProgram.setUniform("uTextures", uTextures);
glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size()));
textures.clear();
uModels.clear();
uTextures.clear();
}
textures.push_back(image.get().texture());
image.get().texture().bind(static_cast<GLint>(textures.size()-1));
uTextures.push_back(static_cast<GLint>(textures.size()-1));
uModels.push_back(image.get().transformation().model());
}
}
if(!textures.empty()) {
this->_imageProgram.setUniform("uModel", uModels);
this->_imageProgram.setUniform("uTextures", uTextures);
glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size()));
}
}
void QuadInstancedModule::draw(ref_set<Sprite> & sprites, const Window &, const Camera & camera, const TextureArray &) const {
this->_vao.bind();
this->_spriteProgram.use();
this->_spriteProgram.setUniform("uProj", camera.projection());
this->_spriteProgram.setUniform("uView", camera.view());
std::vector<std::reference_wrapper<const Texture>> textures;
std::vector<glm::mat4> uModels;
std::vector<glm::vec4> uFrames;
std::vector<glm::vec2> uSizes;
std::vector<GLint> uTextures;
static auto uSampler = array_generator<GLint, 32>().array;
this->_spriteProgram.setUniform("uSampler", uSampler);
for(auto & image : sprites) {
std::vector<std::reference_wrapper<const Texture>>::iterator it = std::find(textures.begin(), textures.end(), image.get().texture());
if(it != textures.end()) {
uModels.push_back(image.get().transformation().model());
uFrames.push_back(image.get().frame());
uSizes.push_back({it->get().width(), it->get().height()});
uTextures.push_back(static_cast<GLint>(it - textures.begin()));
}
else {
if(textures.size() >= 8 || uModels.size() >= 124) {
this->_spriteProgram.setUniform("uModel", uModels);
this->_spriteProgram.setUniform("uTextures", uTextures);
this->_spriteProgram.setUniform("uFrames", uFrames);
this->_spriteProgram.setUniform("uSizes", uSizes);
glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size()));
textures.clear();
uModels.clear();
uTextures.clear();
uSizes.clear();
}
textures.push_back(image.get().texture());
image.get().texture().bind(static_cast<GLint>(textures.size()-1));
uTextures.push_back(static_cast<GLint>(textures.size()-1));
uModels.push_back(image.get().transformation().model());
uFrames.push_back(image.get().frame());
uSizes.push_back({image.get().texture().width(), image.get().texture().height()});
}
}
if(!textures.empty()) {
this->_spriteProgram.setUniform("uModel", uModels);
this->_spriteProgram.setUniform("uTextures", uTextures);
this->_spriteProgram.setUniform("uFrames", uFrames);
this->_spriteProgram.setUniform("uSizes", uSizes);
glDrawArraysInstanced(Quads::Primitive(), 0, static_cast<GLsizei>(this->_vbo.size()), static_cast<GLsizei>(uModels.size()));
}
}
}
\ No newline at end of file
#pragma once
#include "Module.hpp"
#include <engine/graphics/back/buffers/VertexArray.hpp>
#include <engine/graphics/back/buffers/VerticeBuffer.hpp>
#include <engine/graphics/back/shaders/Program.hpp>
namespace megu {
class Image;
class Sprite;
class QuadInstancedModule : public Module<ref_set<Image>>, public Module<ref_set<Sprite>> {
public:
QuadInstancedModule();
void draw(ref_set<Image> &, const Window &, const Camera &, const TextureArray &) const override;
void draw(ref_set<Sprite> &, const Window &, const Camera &, const TextureArray &) const override;
private:
VertexArray _vao;
VerticeBuffer _vbo;
Program _imageProgram;
Program _spriteProgram;
};
}
\ No newline at end of file
......@@ -2,7 +2,7 @@
namespace megu {
Image::Image(const std::filesystem::path & path) {
this->load(path);
this->load(path, true);
}
Image::Image(const Texture & texture) {
......
......@@ -10,9 +10,9 @@ namespace megu {
public:
Renderable() = delete;
template <class T, class M>
Renderable(T & object, M & module)
: _pimpl(std::make_unique<RenderableModel<T, M>>(object, module)) {}
template <class T>
Renderable(T & object, Module<T> * module)
: _pimpl(std::make_unique<RenderableModel<T>>(object, module)) {}
Renderable(const Renderable & src) {
this->_pimpl = src._pimpl->clone();
......@@ -34,14 +34,13 @@ namespace megu {
virtual std::unique_ptr<RenderableConcept> clone() const = 0;
};
template <class T, class M>
template <class T>
struct RenderableModel : public RenderableConcept {
RenderableModel(T & v, M & m)
RenderableModel(T & v, Module<T> * m)
: _object{ v }, _module{ m } {}
void render(const Window & window, const Camera & camera, const TextureArray & array) const override {
this->_module.draw(this->_object, window, camera, array);
this->_module->draw(this->_object, window, camera, array);
}
std::unique_ptr<RenderableConcept> clone() const override {
......@@ -49,7 +48,7 @@ namespace megu {
}
T & _object;
M & _module;
Module<T> * _module;
};
friend void render_ext(Renderable & renderable, const Window & window, const Camera & camera, const TextureArray & array) {
......
#include "Sprite.hpp"
namespace megu {
Sprite::Sprite(const Texture & texture)
: _frame(0, 0, texture.width(), texture.height()), _texture(texture) {
this->_transformation.scale(static_cast<float>(texture.width()), static_cast<float>(texture.height()));
Sprite::Sprite(const std::filesystem::path & path)
: _frame(0, 0, 0, 0) {
this->load(path, true);
}
Sprite::Sprite(const Texture & texture, const glm::vec4 & frame)
: _frame(frame), _texture(texture) {
this->_transformation.move(frame.x, frame.y);
this->_transformation.scale(frame.z, frame.w);
void Sprite::load(const std::filesystem::path & path, bool flip) {
TextureBuffer buffer;
buffer.load(path, flip);
this->load(buffer);
}
void Sprite::load(const TextureBuffer & buffer) {
this->setSize({buffer.width(), buffer.height()});
this->_texture.store(buffer);
}
void Sprite::link(const Texture & texture) {
this->setSize({texture.width(), texture.height()});
this->_texture = texture;
}
}
\ No newline at end of file
......@@ -4,21 +4,38 @@
#include <engine/graphics/back/textures/Texture.hpp>
#include <engine/graphics/front/geometry/Quads.hpp>
#include <engine/graphics/utility/type.hpp>
namespace megu {
class Sprite {
public:
Sprite(const Texture &);
Sprite(const Texture &, const glm::vec4 &);
using Frame = glm::vec4;
Sprite(const std::filesystem::path &);
inline void setFrame(const Frame & frame) {this->_frame = frame;}
inline void setFrame(const glm::vec4 & frame) {this->_frame = frame;}
inline void setPosition(const Vec2 & pos) {this->_transformation.setPosition(pos.x, pos.y);}
inline void setOrigine(const Vec2 & pos) {this->_transformation.setOrigine(pos.x, pos.y);}
inline void setSize(const Vec2 & size) {this->_transformation.setScaling(size.x, size.y);}
inline void setRotation(float a) {this->_transformation.setRotation(a, Transformable::Axis::Z);}
inline void setLayer(float l) {this->_transformation.setZ(l);}
inline const glm::vec4 & frame() const {return this->_frame;}
inline void move(const Vec2 & pos) {this->_transformation.move({pos.x, pos.y, 0.f});}
inline void scale(const Vec2 & size) {this->_transformation.scale({size.x, size.y, 0.f});}
inline void rotate(float a) {this->_transformation.rotate(a, Transformable::Axis::Z);}
inline const Frame & frame() const {return this->_frame;}
inline const Texture & texture() const {return this->_texture;}
inline const Quads & geometry() const {return this->_geometry;}
inline const Transformable & transformation() const {return this->_transformation;}
void load(const std::filesystem::path &, bool = false);
void load(const TextureBuffer &);
void link(const Texture &);
private:
glm::vec4 _frame;
Frame _frame;
Texture _texture;
Quads _geometry;
Transformable _transformation;
......
#include "isometric_sorter.hpp"
#include <engine/graphics/front/object/Image.hpp>
#include <engine/graphics/front/object/Sprite.hpp>
#include <engine/graphics/back/geometry/Transformable.hpp>
namespace megu {
bool isometric_sorter::operator()(const Image & img1, const Image & img2) const {
if(img1.transformation().z() != img2.transformation().z()) {
return img1.transformation().z() > img2.transformation().z();
bool isometric_sorter::operator()(const Transformable & a, const Transformable & b) const {
if(a.z() != b.z()) {
return a.z() > b.z();
}
if(img1.transformation().y() != img2.transformation().y()) {
return img1.transformation().y() > img2.transformation().y();
if(a.y() != b.y()) {
return a.y() > b.y();
}
if(img1.transformation().x() != img2.transformation().x()) {
return img1.transformation().x() > img2.transformation().x();
if(a.x() != b.x()) {
return a.x() > b.x();
}
return &img1 > &img2;
}
bool isometric_sorter_sprite::operator()(const Sprite & img1, const Sprite & img2) const {
if(img1.transformation().z() != img2.transformation().z()) {
return img1.transformation().z() > img2.transformation().z();
}
if(img1.transformation().y() != img2.transformation().y()) {
return img1.transformation().y() > img2.transformation().y();
}
if(img1.transformation().x() != img2.transformation().x()) {
return img1.transformation().x() > img2.transformation().x();
}
return &img1 > &img2;
return &a > &b;
}
}
\ No newline at end of file
#pragma once
namespace megu {
class Image;
class Sprite;
class Transformable;
class isometric_sorter {
public:
bool operator()(const Image & img1, const Image & img2) const;
};
class isometric_sorter_sprite {
public:
bool operator()(const Sprite & img1, const Sprite & img2) const;
bool operator()(const Transformable & img1, const Transformable & img2) const;
};
}
\ No newline at end of file
#pragma once
namespace megu {
template <class T>
using ref_set = std::set<std::reference_wrapper<T>, reference_sorter<T>>;
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment