From 3a49373d75b65f7ff4331d2a96e3ecbc4ac42f61 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 18 Aug 2022 22:40:34 -0400 Subject: [PATCH] Create a renderer that handles model rendering --- examples/dev_testing/src/main.cpp | 26 ++++++++- include/simpleengine/gfx/renderer.h | 47 +++++++++++++++ include/simpleengine/gfx/vao.h | 32 ++++++++++- include/simpleengine/gfx/vbo.h | 13 ++++- src/gfx/model.cpp | 6 +- src/gfx/renderer.cpp | 89 +++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+), 10 deletions(-) create mode 100644 include/simpleengine/gfx/renderer.h create mode 100644 src/gfx/renderer.cpp diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index 6252973..af791d1 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,6 +1,7 @@ #include "simpleengine/camera.h" #include "simpleengine/gfx/light.h" #include "simpleengine/gfx/model.h" +#include "simpleengine/gfx/renderer.h" #include "simpleengine/gfx/texture.h" #include "simpleengine/objects/3d/terrain.h" #include "simpleengine/vector.h" @@ -32,6 +33,22 @@ CMRC_DECLARE(resource_shaders); namespace se = simpleengine; +class RendererEvent : public se::Event { +public: + RendererEvent(se::gfx::Renderer renderer) : se::Event(), renderer(renderer) {} + ~RendererEvent() = default; + + se::gfx::Renderer renderer; + + virtual void update(const float& delta_time) override { + + } + + virtual void render(GLFWwindow* target) override { + this->renderer.render(nullptr); + } +}; + std::string read_resource_shader(const std::string& path) { auto fs = cmrc::resource_shaders::get_filesystem(); cmrc::file vertex_file = fs.open(path); @@ -139,7 +156,14 @@ int main(int argc, char *argv[]) { auto cube = std::make_shared(game.get_window(), core_shader, cube_vertices, cube_indicies); cube->calculate_normals(); cube->translate(3.5f, 0.f, 0.f); - game.add_event(cube); + //game.add_event(cube); + + auto renderer = std::make_shared(game.get_window(), core_shader); + renderer->add_model(white_texture, cube); + game.add_event(renderer); + + /* auto r_event = std::make_shared(renderer); + game.add_event(r_event); */ auto camera = std::make_shared(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0)); game.add_event(camera); diff --git a/include/simpleengine/gfx/renderer.h b/include/simpleengine/gfx/renderer.h new file mode 100644 index 0000000..ea2686c --- /dev/null +++ b/include/simpleengine/gfx/renderer.h @@ -0,0 +1,47 @@ +#pragma once + +#include "texture.h" +#include "shader.h" +//#include "renderable.h" +#include "model.h" + +#include + +namespace simpleengine::gfx { + class Renderer : public simpleengine::Renderable { + private: + GLFWwindow* window; + public: + class RenderingModel { + public: + RenderingModel(std::shared_ptr model, simpleengine::gfx::Texture texture, gfx::VBO ebo, + gfx::VBO vbo, gfx::VAO vao) : model(model), texture(texture), ebo(ebo), vbo(vbo), vao(vao) { + + } + + std::shared_ptr model; + simpleengine::gfx::Texture texture; + + gfx::VBO ebo; + gfx::VBO vbo; + gfx::VAO vao; + }; + + gfx::Shader shader; + std::vector rendering_models; + + Renderer(GLFWwindow* window, gfx::Shader shader); + Renderer(GLFWwindow* window, GLuint shader_program); + + virtual void add_model(simpleengine::gfx::Texture texture, std::shared_ptr model); + virtual void remove_model(std::shared_ptr model); + + virtual void initialize(); + + virtual void update(const float& delta_time) override { + + } + + virtual void render(GLFWwindow* target) override; + }; +} \ No newline at end of file diff --git a/include/simpleengine/gfx/vao.h b/include/simpleengine/gfx/vao.h index 377466a..f66b134 100644 --- a/include/simpleengine/gfx/vao.h +++ b/include/simpleengine/gfx/vao.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #ifdef __linux__ #include #include @@ -15,12 +17,30 @@ namespace simpleengine::gfx { public: GLuint handle; - VAO() { - glCreateVertexArrays(1, &handle); + VAO(GLuint handle) : handle(handle) { + //glCreateVertexArrays(1, &handle); } ~VAO() { - destroy(); + std::cout << "TODO, drop VAO (" << handle << ")" << std::endl; + } + + VAO& operator=(const VAO& other) { + if (this != &other) { + handle = other.handle; + } + + + std::cout << "Copied " << handle << std::endl; + + return *this; + } + + static VAO init() { + GLuint handle; + glCreateVertexArrays(1, &handle); + + return VAO(handle); } void destroy() { @@ -29,6 +49,12 @@ namespace simpleengine::gfx { void bind() const { glBindVertexArray(handle); + + GLenum err = glGetError(); + if (err != GL_NO_ERROR) { + //fprintf(stderr, "Ran into opengl error: 0x%x\n", err); + //std::cerr << "Ran into enum error: " + } } // TODO: Fix this. diff --git a/include/simpleengine/gfx/vbo.h b/include/simpleengine/gfx/vbo.h index 49214a4..a3099f8 100644 --- a/include/simpleengine/gfx/vbo.h +++ b/include/simpleengine/gfx/vbo.h @@ -15,16 +15,23 @@ namespace simpleengine::gfx { GLint type; bool dynamic; - VBO() = default; + //VBO() = default; - VBO(GLint type, bool dynamic) : type(type), dynamic(dynamic) { - glGenBuffers(1, &handle); + VBO(GLuint handle, GLint type, bool dynamic) : type(type), dynamic(dynamic), handle(handle) { + //glGenBuffers(1, &handle); } ~VBO() { destroy(); } + static VBO init(GLint type, bool dynamic) { + GLuint handle; + glGenBuffers(1, &handle); + + return VBO(handle, type, dynamic); + } + void destroy() { glDeleteBuffers(1, &handle); } diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index d53f425..4ceecfa 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -2,10 +2,10 @@ namespace simpleengine::gfx { Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies) : - simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)), - ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)) { + simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), + ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)), vao(gfx::VAO::init()) { - setup_vertices(); + //setup_vertices(); } Model::Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, std::vector indicies) : diff --git a/src/gfx/renderer.cpp b/src/gfx/renderer.cpp new file mode 100644 index 0000000..20392d8 --- /dev/null +++ b/src/gfx/renderer.cpp @@ -0,0 +1,89 @@ +#include "gfx/renderer.h" + +namespace simpleengine::gfx { + Renderer::Renderer(GLFWwindow* window, gfx::Shader shader): window(window), shader(shader) { + + } + + Renderer::Renderer(GLFWwindow* window, GLuint shader_program): Renderer(window, + gfx::Shader(shader_program)) { + + } + + void Renderer::add_model(simpleengine::gfx::Texture texture, std::shared_ptr model) { + auto ebo = gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false); + auto vbo = gfx::VBO::init(GL_ARRAY_BUFFER, false); + auto vao = gfx::VAO::init(); + + // 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 model) { + std::cerr << "Removing model is unimplemented!" << std::endl; + } + + void Renderer::initialize() { + std::cout << "Base Renderer initialized" << std::endl; + } + + void Renderer::render(GLFWwindow* target) { + shader.use(); + + for (RenderingModel& rendering : rendering_models) { + std::shared_ptr& model = rendering.model; + + shader.use(); + shader.set_uniform_matrix_4f("transform_matrix", model->transform_matrix, false); + + 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); + } + + /* 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(); + } +} \ No newline at end of file