Implement ECS in the renderer. Nothing is shown yet though
This commit is contained in:
parent
61ff63bef0
commit
371534a01a
|
@ -1,5 +1,6 @@
|
||||||
# Don't track content of these folders
|
# Don't track content of these folders
|
||||||
.vscode/*
|
.vscode/*
|
||||||
|
.VSCodeCounter
|
||||||
CMakeFiles/*
|
CMakeFiles/*
|
||||||
.vs/*
|
.vs/*
|
||||||
out/*
|
out/*
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "simpleengine/camera.h"
|
#include "simpleengine/camera.h"
|
||||||
|
#include "simpleengine/ecs/component/model_componenet.h"
|
||||||
|
#include "simpleengine/ecs/entity.h"
|
||||||
#include "simpleengine/gfx/light.h"
|
#include "simpleengine/gfx/light.h"
|
||||||
#include "simpleengine/gfx/material.h"
|
#include "simpleengine/gfx/material.h"
|
||||||
#include "simpleengine/gfx/model.h"
|
#include "simpleengine/gfx/model.h"
|
||||||
|
@ -13,7 +15,7 @@
|
||||||
#include <simpleengine/vertex.h>
|
#include <simpleengine/vertex.h>
|
||||||
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
#include <simpleengine/gfx/shaders/core_3d_shader.h>
|
||||||
|
|
||||||
#include <simpleengine/scene.h>
|
//#include <simpleengine/scene.h>
|
||||||
|
|
||||||
#include <glm/ext/matrix_clip_space.hpp>
|
#include <glm/ext/matrix_clip_space.hpp>
|
||||||
#include <glm/fwd.hpp>
|
#include <glm/fwd.hpp>
|
||||||
|
@ -141,14 +143,25 @@ int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
se::gfx::Material material(white_texture, 1.f, 0.f, 0.f, 0.f, 0.f);
|
se::gfx::Material material(white_texture, 1.f, 0.f, 0.f, 0.f, 0.f);
|
||||||
|
|
||||||
auto cube = std::make_shared<se::gfx::Model>(cube_vertices, cube_indicies,
|
auto entity = std::make_shared<simpleengine::Entity>();
|
||||||
|
se::gfx::Model model(cube_vertices, cube_indicies, std::optional<se::gfx::Material>(material));
|
||||||
|
model.calculate_normals();
|
||||||
|
|
||||||
|
se::ModelComponent model_component(model);
|
||||||
|
|
||||||
|
entity->add_component(model_component);
|
||||||
|
entity->translate(3.5f, 0.f, 0.f);
|
||||||
|
|
||||||
|
/* auto cube = std::make_shared<se::gfx::Model>(cube_vertices, cube_indicies,
|
||||||
std::optional<se::gfx::Material>(material));
|
std::optional<se::gfx::Material>(material));
|
||||||
cube->calculate_normals();
|
cube->calculate_normals();
|
||||||
cube->translate(3.5f, 0.f, 0.f);
|
cube->translate(3.5f, 0.f, 0.f); */
|
||||||
//game.add_event(cube);
|
//game.add_event(cube);
|
||||||
|
|
||||||
/* auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
|
auto renderer = std::make_shared<se::gfx::Renderer>(game.get_window(), core_shader);
|
||||||
renderer->add_model(white_texture, cube);
|
renderer->submit_entity(entity);
|
||||||
|
game.add_event(renderer);
|
||||||
|
/* renderer->add_model(white_texture, cube);
|
||||||
game.add_event(renderer); */
|
game.add_event(renderer); */
|
||||||
|
|
||||||
/* auto r_event = std::make_shared<RendererEvent>(renderer);
|
/* auto r_event = std::make_shared<RendererEvent>(renderer);
|
||||||
|
@ -157,5 +170,9 @@ int main(int argc, char *argv[]) {
|
||||||
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
|
auto camera = std::make_shared<se::Camera>(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0));
|
||||||
game.add_event(camera);
|
game.add_event(camera);
|
||||||
|
|
||||||
return game.run();
|
int res = game.run();
|
||||||
|
|
||||||
|
renderer->destroy();
|
||||||
|
|
||||||
|
return res;
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "gfx/model.h"
|
#include "../../gfx/model.h"
|
||||||
#include "event/event.h"
|
#include "../../event/event.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -12,16 +12,20 @@ namespace simpleengine {
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Component : public simpleengine::Event {
|
class Component : public simpleengine::Event {
|
||||||
|
private:
|
||||||
|
static uint32_t incrementing_handle;
|
||||||
|
uint32_t handle;
|
||||||
public:
|
public:
|
||||||
Component() = default;
|
Component() {
|
||||||
|
handle = incrementing_handle++;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_handle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
virtual void update(const float& delta_time) override {
|
||||||
std::cout << "Component update" << std::endl;
|
std::cout << "Component update" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<gfx::Model>> get_renderable_models() {
|
|
||||||
std::cout << "Got renderables" << std::endl;
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "component.h"
|
||||||
|
#include "../../gfx/model.h"
|
||||||
|
#include "../../gfx/material.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
/**
|
||||||
|
* @brief A Model is a object that will be shown on the screen by a renderer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class ModelComponent : public simpleengine::Component {
|
||||||
|
public:
|
||||||
|
gfx::Model model;
|
||||||
|
//gfx::Material material;
|
||||||
|
|
||||||
|
ModelComponent(gfx::Model model) : model(model) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(const float& delta_time) override {
|
||||||
|
std::cout << "Model Component update" << std::endl;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "component/component.h"
|
||||||
|
#include "../transformable.h"
|
||||||
|
#include "../util.h"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
#include <random>
|
||||||
|
#include <bitset>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
/**
|
||||||
|
* @brief A Model is a object that will be shown on the screen by a renderer.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
class Entity : public simpleengine::Event, public simpleengine::Transformable {
|
||||||
|
private:
|
||||||
|
static uint32_t incrementing_handle;
|
||||||
|
uint32_t handle;
|
||||||
|
public:
|
||||||
|
std::vector<std::shared_ptr<Component>> components;
|
||||||
|
|
||||||
|
Entity() : components({}) {
|
||||||
|
handle = incrementing_handle++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Entity() : components({}) {
|
||||||
|
std::random_device rd; // obtain a random number from hardware
|
||||||
|
std::mt19937 gen(rd()); // seed the generator
|
||||||
|
std::uniform_int_distribution<uint16_t> distr(1, std::numeric_limits<std::uint16_t>::max());
|
||||||
|
|
||||||
|
uint16_t num = distr(gen);
|
||||||
|
uint32_t pid = simpleengine::util::get_current_pid();
|
||||||
|
|
||||||
|
handle |= num;
|
||||||
|
handle |= (pid << 16);
|
||||||
|
|
||||||
|
std::string binary = std::bitset<16>(num).to_string();
|
||||||
|
std::cout << "Entity handle: " << binary << std::endl;
|
||||||
|
|
||||||
|
} */
|
||||||
|
|
||||||
|
Entity(std::vector<std::shared_ptr<Component>> components) : Entity() {
|
||||||
|
this->components = components;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t get_handle() {
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void update(const float& delta_time) override {
|
||||||
|
std::cout << "Update entity" << std::endl;
|
||||||
|
|
||||||
|
for (auto& component : components) {
|
||||||
|
component->update(delta_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool has_component() const {
|
||||||
|
for (const auto& comp : components) {
|
||||||
|
if (std::dynamic_pointer_cast<T>(comp)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
std::shared_ptr<T> get_component() const {
|
||||||
|
for (const auto& comp : components) {
|
||||||
|
if (std::shared_ptr<T> dyn_comp = std::dynamic_pointer_cast<T>(comp); dyn_comp) {
|
||||||
|
return dyn_comp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void add_component(std::shared_ptr<T> component) {
|
||||||
|
static_assert(std::is_base_of_v<Component, T>, "Component class must derive from simpleengine::Component");
|
||||||
|
|
||||||
|
// Only allow one type of the same component
|
||||||
|
assert(!has_component<T>()); // TODO: Don't assert, give an error
|
||||||
|
components.push_back(component);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void add_component(T component) {
|
||||||
|
static_assert(std::is_base_of_v<Component, T>, "Component class must derive from simpleengine::Component");
|
||||||
|
|
||||||
|
// Only allow one type of the same component
|
||||||
|
assert(!has_component<T>()); // TODO: Don't assert, give an error
|
||||||
|
components.push_back(std::make_shared<T>(component));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "component.h"
|
|
||||||
#include "transformable.h"
|
|
||||||
|
|
||||||
#include <iterator>
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace simpleengine {
|
|
||||||
/**
|
|
||||||
* @brief A Model is a object that will be shown on the screen by a renderer.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
class Entity : public simpleengine::Event, public simpleengine::Transformable {
|
|
||||||
public:
|
|
||||||
std::vector<Component> components;
|
|
||||||
|
|
||||||
Entity(std::vector<Component> components = {}) : components(components) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
|
||||||
std::cout << "Update entity" << std::endl;
|
|
||||||
|
|
||||||
for (auto& component : components) {
|
|
||||||
component.update(delta_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::vector<std::shared_ptr<gfx::Model>> get_renderable_models() {
|
|
||||||
std::cout << "Got renderables from entity" << std::endl;
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<gfx::Model>> models;
|
|
||||||
for (auto& component : components) {
|
|
||||||
std::vector<std::shared_ptr<gfx::Model>> comp_models = component.get_renderable_models();
|
|
||||||
|
|
||||||
// Move comp_models into models
|
|
||||||
models.insert(models.end(), std::make_move_iterator(comp_models.begin()),
|
|
||||||
std::make_move_iterator(comp_models.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return models;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -23,6 +23,7 @@ namespace simpleengine::gfx {
|
||||||
std::vector<LitVertex> vertices;
|
std::vector<LitVertex> vertices;
|
||||||
std::vector<GLuint> indicies;
|
std::vector<GLuint> indicies;
|
||||||
|
|
||||||
|
Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material);
|
||||||
Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
|
Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies = std::vector<GLuint>(), std::optional<Material> material = std::nullopt);
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override;
|
virtual void update(const float& delta_time) override;
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../ecs/entity.h"
|
||||||
|
#include "material.h"
|
||||||
#include "texture.h"
|
#include "texture.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
//#include "renderable.h"
|
//#include "renderable.h"
|
||||||
#include "model.h"
|
#include "model.h"
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
|
@ -12,35 +15,58 @@ namespace simpleengine::gfx {
|
||||||
private:
|
private:
|
||||||
GLFWwindow* window;
|
GLFWwindow* window;
|
||||||
public:
|
public:
|
||||||
class RenderingModel {
|
class RenderingBuffers {
|
||||||
public:
|
public:
|
||||||
RenderingModel(std::shared_ptr<simpleengine::gfx::Model> model, simpleengine::gfx::Texture texture, gfx::VBO ebo,
|
gfx::Model& model;
|
||||||
gfx::VBO vbo, gfx::VAO vao) : model(model), texture(texture), ebo(ebo), vbo(vbo), vao(vao) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<simpleengine::gfx::Model> model;
|
|
||||||
simpleengine::gfx::Texture texture;
|
|
||||||
|
|
||||||
gfx::VBO ebo;
|
gfx::VBO ebo;
|
||||||
gfx::VBO vbo;
|
gfx::VBO vbo;
|
||||||
gfx::VAO vao;
|
gfx::VAO vao;
|
||||||
|
|
||||||
|
RenderingBuffers(gfx::Model& model, gfx::VBO ebo, gfx::VBO vbo, gfx::VAO vao) : model(model), ebo(ebo), vbo(vbo), vao(vao) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* std::vector<LitVertex>& vertices;
|
||||||
|
std::vector<GLuint>& indicies; */
|
||||||
|
/// If these buffers were rendered last update.
|
||||||
|
//bool rendered;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RenderingModel {
|
||||||
|
public:
|
||||||
|
std::shared_ptr<simpleengine::Entity> entity;
|
||||||
|
std::unordered_map<uint32_t, RenderingBuffers> rendering_buffers;
|
||||||
|
|
||||||
|
RenderingModel(std::shared_ptr<simpleengine::Entity> entity) : entity(entity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create and delete buffers for new and old components in entity.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void update_buffers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroy the buffers
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void destroy_buffers();
|
||||||
};
|
};
|
||||||
|
|
||||||
gfx::Shader shader;
|
gfx::Shader shader;
|
||||||
std::vector<RenderingModel> rendering_models;
|
std::unordered_map<uint32_t, RenderingModel> rendering_models;
|
||||||
|
|
||||||
Renderer(GLFWwindow* window, gfx::Shader shader);
|
Renderer(GLFWwindow* window, gfx::Shader shader);
|
||||||
Renderer(GLFWwindow* window, GLuint shader_program);
|
Renderer(GLFWwindow* window, GLuint shader_program);
|
||||||
|
|
||||||
virtual void add_model(simpleengine::gfx::Texture texture, std::shared_ptr<simpleengine::gfx::Model> model);
|
virtual void submit_entity(std::shared_ptr<simpleengine::Entity> entity);
|
||||||
virtual void remove_model(std::shared_ptr<simpleengine::gfx::Model> model);
|
virtual bool withdraw_entity(std::shared_ptr<simpleengine::Entity> entity);
|
||||||
|
|
||||||
virtual void initialize();
|
virtual void initialize();
|
||||||
|
virtual void destroy();
|
||||||
|
|
||||||
virtual void update(const float& delta_time) override {
|
virtual void update(const float& delta_time) override;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void render(GLFWwindow* target) override;
|
virtual void render(GLFWwindow* target) override;
|
||||||
};
|
};
|
||||||
|
|
|
@ -54,7 +54,6 @@ namespace simpleengine::gfx {
|
||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
if (err != GL_NO_ERROR) {
|
if (err != GL_NO_ERROR) {
|
||||||
fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
|
fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
|
||||||
//std::cerr << "Ran into enum error: "
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +90,12 @@ namespace simpleengine::gfx {
|
||||||
// rarely happens. Modifying other VAOs requires a call to glBindVertexArray anyways so we generally
|
// rarely happens. Modifying other VAOs requires a call to glBindVertexArray anyways so we generally
|
||||||
// don't unbind VAOs (nor VBOs) when it's not directly necessary.
|
// don't unbind VAOs (nor VBOs) when it's not directly necessary.
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
// TODO: Handle opengl errors EVERYWHERE
|
||||||
|
GLenum err = glGetError();
|
||||||
|
if (err != GL_NO_ERROR) {
|
||||||
|
fprintf(stderr, "Ran into opengl error: 0x%x\n", err);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void disable_attrib(const VBO& vbo, GLuint index) const {
|
void disable_attrib(const VBO& vbo, GLuint index) const {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "windows.h"
|
||||||
|
#elif __linux__
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace simpleengine {
|
||||||
|
namespace util {
|
||||||
|
#ifdef _WIN32
|
||||||
|
inline uint32_t get_current_pid(LPCTSTR ProcessName) // non-conflicting function name
|
||||||
|
{
|
||||||
|
return GetCurrentProcessId();
|
||||||
|
}
|
||||||
|
#elif __linux__
|
||||||
|
inline uint32_t get_current_pid() {
|
||||||
|
return ::getpid();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "ecs/component/component.h"
|
||||||
|
|
||||||
|
uint32_t simpleengine::Component::incrementing_handle = 0;
|
|
@ -0,0 +1,3 @@
|
||||||
|
#include "ecs/entity.h"
|
||||||
|
|
||||||
|
uint32_t simpleengine::Entity::incrementing_handle = 0;
|
|
@ -1,6 +1,12 @@
|
||||||
#include "gfx/model.h"
|
#include "gfx/model.h"
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
|
Model::Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, Material material) :
|
||||||
|
material(std::make_optional(material)), vertices(vertices), indicies(indicies) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Model::Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
|
Model::Model(std::vector<LitVertex> vertices, std::vector<GLuint> indicies, std::optional<Material> material) :
|
||||||
material(material), vertices(vertices), indicies(indicies) {
|
material(material), vertices(vertices), indicies(indicies) {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,65 @@
|
||||||
#include "gfx/renderer.h"
|
#include "gfx/renderer.h"
|
||||||
|
#include "ecs/component/component.h"
|
||||||
|
#include "ecs/entity.h"
|
||||||
|
#include "gfx/model.h"
|
||||||
|
#include "renderable.h"
|
||||||
|
|
||||||
|
#include "ecs/component/model_componenet.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace simpleengine::gfx {
|
namespace simpleengine::gfx {
|
||||||
|
void Renderer::RenderingModel::update_buffers() {
|
||||||
|
if (std::shared_ptr<ModelComponent> comp = entity->get_component<simpleengine::ModelComponent>()) {
|
||||||
|
auto iter = rendering_buffers.find(comp->get_handle());
|
||||||
|
if (iter == rendering_buffers.end()) {
|
||||||
|
std::cout << "Creating buffer for ModelComponent (" << comp->get_handle() << ")..." << std::endl;
|
||||||
|
|
||||||
|
auto ebo = gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false);
|
||||||
|
auto vbo = gfx::VBO::init(GL_ARRAY_BUFFER, false);
|
||||||
|
auto vao = gfx::VAO::init();
|
||||||
|
auto& model = comp->model;
|
||||||
|
|
||||||
|
// Create and setup the EBO, VAO, and VBOs.
|
||||||
|
vao.bind();
|
||||||
|
vbo.buffer(model.vertices.data(), 0, sizeof(LitVertex) * model.vertices.size());
|
||||||
|
if (!model.indicies.empty()) {
|
||||||
|
ebo.buffer(model.indicies.data(), 0, sizeof(GLuint) * model.indicies.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Enable VAO attributes
|
||||||
|
vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position));
|
||||||
|
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color));
|
||||||
|
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal));
|
||||||
|
vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord));
|
||||||
|
vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id));
|
||||||
|
|
||||||
|
RenderingBuffers buffers(comp->model, ebo, vbo, vao);
|
||||||
|
rendering_buffers.emplace(comp->get_handle(), buffers);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindVertexArray(0);
|
||||||
|
|
||||||
|
std::cout << "Finished creating ModelComponent buffers!" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "Already exists" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::RenderingModel::destroy_buffers() {
|
||||||
|
std::cout << "Destroying buffers for entity!" << std::endl;
|
||||||
|
|
||||||
|
// Iterate through all buffer lists and destroy each inner buffer.
|
||||||
|
for (auto& pair : rendering_buffers) {
|
||||||
|
RenderingBuffers& buffers = pair.second;
|
||||||
|
|
||||||
|
buffers.ebo.destroy();
|
||||||
|
buffers.vao.destroy();
|
||||||
|
buffers.vbo.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Renderer::Renderer(GLFWwindow* window, gfx::Shader shader): window(window), shader(shader) {
|
Renderer::Renderer(GLFWwindow* window, gfx::Shader shader): window(window), shader(shader) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,78 +69,77 @@ namespace simpleengine::gfx {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::add_model(simpleengine::gfx::Texture texture, std::shared_ptr<simpleengine::gfx::Model> model) {
|
void Renderer::submit_entity(std::shared_ptr<simpleengine::Entity> entity) {
|
||||||
auto ebo = gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false);
|
std::cout << "Submitting entity (" << entity->get_handle() << ")..." << std::endl;
|
||||||
auto vbo = gfx::VBO::init(GL_ARRAY_BUFFER, false);
|
auto it = rendering_models.emplace(entity->get_handle(), entity);
|
||||||
auto vao = gfx::VAO::init();
|
it.first->second.update_buffers();
|
||||||
|
|
||||||
// Create and setup the EBO, VAO, and VBOs.
|
|
||||||
vao.bind();
|
|
||||||
vbo.buffer(model->vertices.data(), 0, sizeof(LitVertex) * model->vertices.size());
|
|
||||||
if (!model->indicies.empty()) {
|
|
||||||
ebo.buffer(model->indicies.data(), 0, model->indicies.size() * sizeof(GLuint));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable VAO attributes
|
|
||||||
vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position));
|
|
||||||
vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color));
|
|
||||||
vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal));
|
|
||||||
vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord));
|
|
||||||
vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id));
|
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
|
||||||
glBindVertexArray(0);
|
|
||||||
|
|
||||||
// Create the RenderingModel struct and store it in the vector for later.
|
|
||||||
RenderingModel rendering_model( model, texture, ebo, vbo, vao);
|
|
||||||
rendering_models.push_back(rendering_model);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::remove_model(std::shared_ptr<simpleengine::gfx::Model> model) {
|
bool Renderer::withdraw_entity(std::shared_ptr<simpleengine::Entity> entity) {
|
||||||
std::cerr << "Removing model is unimplemented!" << std::endl;
|
std::cout << "Withdrawing entity (" << entity->get_handle() << ")...";
|
||||||
|
auto it = rendering_models.find(entity->get_handle());
|
||||||
|
|
||||||
|
if (it != rendering_models.end()) {
|
||||||
|
it->second.destroy_buffers();
|
||||||
|
rendering_models.erase(it);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Renderer::update(const float& delta_time) {
|
||||||
|
this->render(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Renderer::initialize() {
|
void Renderer::initialize() {
|
||||||
std::cout << "Base Renderer initialized" << std::endl;
|
std::cout << "Base Renderer initialized" << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Renderer::destroy() {
|
||||||
|
std::cout << "Destroying renderer..." << std::endl;
|
||||||
|
|
||||||
|
for (auto& [handle, rendering] : rendering_models) {
|
||||||
|
rendering.destroy_buffers();
|
||||||
|
//rendering.entity->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Renderer::render(GLFWwindow* target) {
|
void Renderer::render(GLFWwindow* target) {
|
||||||
shader.use();
|
shader.use();
|
||||||
|
|
||||||
for (RenderingModel& rendering : rendering_models) {
|
for (auto& [handle, rendering] : rendering_models) {
|
||||||
std::shared_ptr<Model>& model = rendering.model;
|
if (rendering.rendering_buffers.size() > 0) {
|
||||||
|
std::shared_ptr<Entity>& entity = rendering.entity;
|
||||||
|
|
||||||
shader.use();
|
shader.set_uniform_matrix_4f("transform_matrix", entity->transform_matrix, false);
|
||||||
shader.set_uniform_matrix_4f("transform_matrix", model->transform_matrix, false);
|
|
||||||
|
|
||||||
rendering.vao.bind();
|
for (const auto& pair : rendering.rendering_buffers) {
|
||||||
if (model->indicies.empty()) {
|
const RenderingBuffers& buffers = pair.second;
|
||||||
glDrawArrays(GL_TRIANGLES, 0, model->vertices.size());
|
Model& model = buffers.model;
|
||||||
} else {
|
std::optional<Material>& material = model.material;
|
||||||
glDrawElements(GL_TRIANGLES, model->indicies.size(), GL_UNSIGNED_INT, 0);
|
|
||||||
|
shader.set_uniform_int("u_textures", 0, false);
|
||||||
|
|
||||||
|
if (material.has_value()) {
|
||||||
|
//Material& material = material
|
||||||
|
shader.set_uniform_float("u_texture_shine", material->shine, false);
|
||||||
|
shader.set_uniform_float("u_texture_reflectivity", material->reflectivity, false);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTextureUnit(0, material->texture.get_texture_id());
|
||||||
|
material->texture.bind();
|
||||||
|
}
|
||||||
|
|
||||||
|
buffers.vao.bind();
|
||||||
|
if (model.indicies.empty()) {
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, model.vertices.size());
|
||||||
|
} else {
|
||||||
|
glDrawElements(GL_TRIANGLES, model.indicies.size(), GL_UNSIGNED_INT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* const Texture& texture = rendering.texture;
|
|
||||||
|
|
||||||
shader.set_uniform_matrix_4f("transform_matrix", model->transform_matrix, false);
|
|
||||||
|
|
||||||
const int tex_id = 0;
|
|
||||||
|
|
||||||
// On a batch renderer, you would set an array.
|
|
||||||
shader.set_uniform_int("u_textures", tex_id, false);
|
|
||||||
shader.set_uniform_float("u_texture_shine", 1.f, false);
|
|
||||||
shader.set_uniform_float("u_texture_reflectivity", 0.f, false);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0 + tex_id);
|
|
||||||
glBindTextureUnit(tex_id, texture.get_texture_id());
|
|
||||||
texture.bind();
|
|
||||||
|
|
||||||
rendering.vao.bind();
|
|
||||||
if (model->indicies.empty()) {
|
|
||||||
glDrawArrays(GL_TRIANGLES, 0, model->vertices.size());
|
|
||||||
} else {
|
|
||||||
glDrawElements(GL_TRIANGLES, model->indicies.size(), GL_UNSIGNED_INT, 0);
|
|
||||||
} */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
shader.unuse();
|
shader.unuse();
|
||||||
|
|
Loading…
Reference in New Issue