diff --git a/CMakeLists.txt b/CMakeLists.txt index b9139a7..54cba84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,13 @@ endif() find_package(GLEW REQUIRED) find_package(glfw3 CONFIG REQUIRED) find_package(glm CONFIG REQUIRED) -find_package(soil2 REQUIRED) + +if (WIN32) + find_package(soil2 CONFIG REQUIRED) +else() + find_package(soil2 REQUIRED) +endif() + find_package(OpenGL REQUIRED) # Link sources @@ -42,7 +48,11 @@ cmrc_add_resource_library( # Link dependencies target_link_libraries(simpleengine PUBLIC GLEW::GLEW) target_link_libraries(simpleengine PUBLIC glfw) -target_link_libraries(simpleengine PUBLIC glm) +if (WIN32) + target_link_libraries(simpleengine PUBLIC glm::glm) +else() + target_link_libraries(simpleengine PUBLIC glm) +endif() target_link_libraries(simpleengine PUBLIC soil2) target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES}) target_link_libraries(simpleengine PRIVATE simpleengine_resources) diff --git a/cmrc b/cmrc index e386a62..a64bea5 160000 --- a/cmrc +++ b/cmrc @@ -1 +1 @@ -Subproject commit e386a629eb537d384811e598a3c96b9ca928f65e +Subproject commit a64bea50c05594c8e7cf1f08e441bb9507742e2e diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index 58aa5b8..1d02513 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -159,6 +159,7 @@ int main(int argc, char *argv[]) { //game.add_event(cube); auto renderer = std::make_shared(game.get_window(), core_shader); + renderer->enable_debug(); renderer->submit_entity(entity); game.add_event(renderer); /* renderer->add_model(white_texture, cube); diff --git a/include/simpleengine/event/event.h b/include/simpleengine/event/event.h index 978332d..9010083 100644 --- a/include/simpleengine/event/event.h +++ b/include/simpleengine/event/event.h @@ -4,8 +4,6 @@ #include -#include - namespace simpleengine { class Event : public simpleengine::Destructable { public: diff --git a/include/simpleengine/gfx/model.h b/include/simpleengine/gfx/model.h index 73ba370..fddf29b 100644 --- a/include/simpleengine/gfx/model.h +++ b/include/simpleengine/gfx/model.h @@ -23,9 +23,16 @@ namespace simpleengine::gfx { std::vector vertices; std::vector indicies; + // Buffer objects + gfx::VBO ebo; + gfx::VBO vbo; + gfx::VAO vao; + Model(std::vector vertices, std::vector indicies, Material material); Model(std::vector vertices, std::vector indicies = std::vector(), std::optional material = std::nullopt); + virtual void destroy() override; + virtual void update(const float& delta_time) override; glm::vec3 compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3); diff --git a/include/simpleengine/gfx/renderer.h b/include/simpleengine/gfx/renderer.h index 5f5f4a6..66baa22 100644 --- a/include/simpleengine/gfx/renderer.h +++ b/include/simpleengine/gfx/renderer.h @@ -15,27 +15,11 @@ namespace simpleengine::gfx { private: GLFWwindow* window; public: - class RenderingBuffers { - public: - gfx::Model& model; - gfx::VBO ebo; - gfx::VBO vbo; - 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& vertices; - std::vector& indicies; */ - /// If these buffers were rendered last update. - //bool rendered; - }; class RenderingModel { public: std::shared_ptr entity; - std::unordered_map rendering_buffers; + std::unordered_map component_models; RenderingModel(std::shared_ptr entity) : entity(entity) { @@ -54,17 +38,19 @@ namespace simpleengine::gfx { void destroy_buffers(); }; - gfx::Shader shader; std::unordered_map rendering_models; + gfx::Shader shader; Renderer(GLFWwindow* window, gfx::Shader shader); Renderer(GLFWwindow* window, GLuint shader_program); - + + void enable_debug(); + virtual void submit_entity(std::shared_ptr entity); virtual bool withdraw_entity(std::shared_ptr entity); virtual void initialize(); - virtual void destroy(); + virtual void destroy() override; virtual void update(const float& delta_time) override; diff --git a/include/simpleengine/gfx/vao.h b/include/simpleengine/gfx/vao.h index 166b277..f9867e0 100644 --- a/include/simpleengine/gfx/vao.h +++ b/include/simpleengine/gfx/vao.h @@ -22,7 +22,7 @@ namespace simpleengine::gfx { } ~VAO() { - std::cout << "TODO, drop VAO (" << handle << ")" << std::endl; + std::cout << "~vao(" << handle << ")" << std::endl; } VAO& operator=(const VAO& other) { @@ -49,18 +49,14 @@ namespace simpleengine::gfx { void bind() const { glBindVertexArray(handle); - - // TODO: Handle opengl errors EVERYWHERE - GLenum err = glGetError(); - if (err != GL_NO_ERROR) { - fprintf(stderr, "Ran into opengl error: 0x%x\n", err); - } } // TODO: Fix this. - void enable_attrib(const VBO& vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset) const { - bind(); - vbo.bind(); + void enable_attrib(const VBO& vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset, bool should_bind = true) const { + if (should_bind) { + bind(); + vbo.bind(); + } // NOTE: glVertexAttribPointer will AUTO-CONVERT integer values to floating point. // Integer vertex attributes must be specified with glVertexAttribIPointer. @@ -82,19 +78,15 @@ namespace simpleengine::gfx { } glEnableVertexAttribArray(index); - // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's - // bound vertex buffer object so afterwards we can safely unbind. - glBindBuffer(GL_ARRAY_BUFFER, 0); + if (should_bind) { + // note that this is allowed, the call to glVertexAttribPointer registered VBO as the vertex attribute's + // bound vertex buffer object so afterwards we can safely unbind. + glBindBuffer(GL_ARRAY_BUFFER, 0); - // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this - // 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. - 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); + // You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this + // 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. + glBindVertexArray(0); } } @@ -103,7 +95,6 @@ namespace simpleengine::gfx { vbo.bind(); glDisableVertexAttribArray(index); - //glDisableVertexArrayAttrib(index); } void set_attrib_value(const VBO& vbo, GLuint index, float f) const { diff --git a/include/simpleengine/gfx/vbo.h b/include/simpleengine/gfx/vbo.h index a3099f8..0148b94 100644 --- a/include/simpleengine/gfx/vbo.h +++ b/include/simpleengine/gfx/vbo.h @@ -1,5 +1,7 @@ #pragma once +#include + #ifdef __linux__ #include #include @@ -15,14 +17,12 @@ namespace simpleengine::gfx { GLint type; bool dynamic; - //VBO() = default; - VBO(GLuint handle, GLint type, bool dynamic) : type(type), dynamic(dynamic), handle(handle) { - //glGenBuffers(1, &handle); + } ~VBO() { - destroy(); + std::cout << "~vbo(" << handle << ")" << std::endl; } static VBO init(GLint type, bool dynamic) { diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index 355821a..38539e5 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -3,15 +3,25 @@ namespace simpleengine::gfx { Model::Model(std::vector vertices, std::vector indicies, Material material) : - material(std::make_optional(material)), vertices(vertices), indicies(indicies) { + material(std::make_optional(material)), 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()) { } Model::Model(std::vector vertices, std::vector indicies, std::optional material) : - material(material), vertices(vertices), indicies(indicies) { + material(material), 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()) { } + void Model::destroy() { + this->ebo.destroy(); + this->vbo.destroy(); + this->vao.destroy(); + } + void Model::update(const float& delta_time) { this->rotate_y(1.f); } diff --git a/src/gfx/renderer.cpp b/src/gfx/renderer.cpp index 837cf73..c64a87e 100644 --- a/src/gfx/renderer.cpp +++ b/src/gfx/renderer.cpp @@ -2,6 +2,7 @@ #include "ecs/component/component.h" #include "ecs/entity.h" #include "gfx/model.h" +#include "gfx/vao.h" #include "renderable.h" #include "ecs/component/model_componenet.h" @@ -11,36 +12,36 @@ namespace simpleengine::gfx { void Renderer::RenderingModel::update_buffers() { if (std::shared_ptr comp = entity->get_component()) { - 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 iter = component_models.find(comp->get_handle()); + if (iter == component_models.end()) { + std::cout << "Enabling buffer attributes 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; + //iter->second = comp->model; + gfx::Model& model = comp->model; + gfx::VBO& vbo = model.vbo; + gfx::VBO& ebo = model.ebo; + gfx::VAO& vao = model.vao; - // 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()); + 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)); - - RenderingBuffers buffers(comp->model, ebo, vbo, vao); - rendering_buffers.emplace(comp->get_handle(), buffers); + vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position), false); + vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color), false); + vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal), false); + vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord), false); + vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id), false); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); - std::cout << "Finished creating ModelComponent buffers!" << std::endl; + component_models.emplace(comp->get_handle(), model); + + std::cout << "Enabled all buffer attributes for ModelComponent" << std::endl; } else { std::cout << "Already exists" << std::endl; } @@ -51,12 +52,8 @@ namespace simpleengine::gfx { 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(); + for (auto& pair : component_models) { + pair.second.destroy(); } } @@ -69,6 +66,19 @@ namespace simpleengine::gfx { } + void debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, + GLsizei length, const GLchar* message, const void* userParam) { + + fprintf( stderr, "%s type = 0x%x, severity = 0x%x, message = %s\n", + ( type == GL_DEBUG_TYPE_ERROR ? "** GL ERROR **" : "" ), + type, severity, message ); + } + + void Renderer::enable_debug() { + glEnable(GL_DEBUG_OUTPUT); + glDebugMessageCallback(debug_message_callback, 0); + } + void Renderer::submit_entity(std::shared_ptr entity) { std::cout << "Submitting entity (" << entity->get_handle() << ")..." << std::endl; auto it = rendering_models.emplace(entity->get_handle(), entity); @@ -102,7 +112,6 @@ namespace simpleengine::gfx { for (auto& [handle, rendering] : rendering_models) { rendering.destroy_buffers(); - //rendering.entity->destroy(); } } @@ -110,14 +119,13 @@ namespace simpleengine::gfx { shader.use(); for (auto& [handle, rendering] : rendering_models) { - if (rendering.rendering_buffers.size() > 0) { + if (rendering.component_models.size() > 0) { std::shared_ptr& entity = rendering.entity; shader.set_uniform_matrix_4f("transform_matrix", entity->transform_matrix, false); - for (const auto& pair : rendering.rendering_buffers) { - const RenderingBuffers& buffers = pair.second; - Model& model = buffers.model; + for (const auto& pair : rendering.component_models) { + Model& model = pair.second; std::optional& material = model.material; shader.set_uniform_int("u_textures", 0, false); @@ -132,7 +140,7 @@ namespace simpleengine::gfx { material->texture.bind(); } - buffers.vao.bind(); + model.vao.bind(); if (model.indicies.empty()) { glDrawArrays(GL_TRIANGLES, 0, model.vertices.size()); } else {