From 862833fc71192233782b4a269053004120dc71ae Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Thu, 25 Nov 2021 16:15:24 -0500 Subject: [PATCH] Fix the 2d triangle, create square, create VAO, and VBO objects. --- .gitignore | 1 + CMakeLists.txt | 2 + examples/dev_testing/src/main.cpp | 49 ++++++++++++-- include/simpleengine/gfx/vao.h | 82 +++++++++++++++++++++++ include/simpleengine/gfx/vbo.h | 42 ++++++++++++ include/simpleengine/shader.h | 9 +-- include/simpleengine/shader_program.h | 4 +- include/simpleengine/shapes/2d/square.h | 67 ++++++++++++++++++ include/simpleengine/shapes/2d/triangle.h | 46 ++++++------- include/simpleengine/vertex.h | 23 +++++++ 10 files changed, 286 insertions(+), 39 deletions(-) create mode 100644 include/simpleengine/gfx/vao.h create mode 100644 include/simpleengine/gfx/vbo.h create mode 100644 include/simpleengine/shapes/2d/square.h create mode 100644 include/simpleengine/vertex.h diff --git a/.gitignore b/.gitignore index 6130c8b..b83b697 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ cmake-build-cmake-build-w10-msvc-debug/* cmake-build-debug-wsl/* build/* .cache/* +c/* # Compiled source # ################### diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f790aa..72db49d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,6 +25,8 @@ target_link_libraries(simpleengine PUBLIC glfw) target_link_libraries(simpleengine PUBLIC glm::glm) target_link_libraries(simpleengine PUBLIC soil2) +include_directories(${GLM_INCLUDE_DIRS}) + # Add examples as a target if the user has them enabled if (SIMPLE_ENGINE_BUILD_EXAMPLES) add_subdirectory(examples) diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index 6f879a5..ae5a752 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -3,19 +3,21 @@ // Github: https://github.com/SeanOMik // +#include "simpleengine/shapes/2d/square.h" #include #include #include #include #include #include +#include #include #include #include +#include #include -#include CMRC_DECLARE(resource_shaders); std::string read_resource_shader(const std::string& path) { @@ -26,7 +28,7 @@ std::string read_resource_shader(const std::string& path) { } int main(int argc, char *argv[]) { - simpleengine::Game game(1280, 720, "SimpleEngine 3D OpenGL - Developer Testing", false); + simpleengine::Game game(640, 480, "SimpleEngine 3D OpenGL - Developer Testing", GLFW_OPENGL_CORE_PROFILE, 4, 4, false); // Load shaders std::string vertex_core = read_resource_shader("shaders/vertex_core.glsl"); @@ -34,14 +36,47 @@ int main(int argc, char *argv[]) { // Create shader program simpleengine::ShaderProgram shader_prog; - shader_prog.add_shader_from_source(simpleengine::ShaderType::Vertex, vertex_core); - shader_prog.add_shader_from_source(simpleengine::ShaderType::Fragment, fragment_core); + shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Vertex, vertex_core); + shader_prog.add_shader_from_source(simpleengine::ShaderType::ST_Fragment, fragment_core); shader_prog.link(); std::shared_ptr base_shader_program = shader_prog.program; - // Create just a simple 2d triangle - std::shared_ptr tri(new simpleengine::shapes_2d::Triangle(base_shader_program)); - game.add_event(tri); + /* std::vector vertices = { + glm::vec3(-0.5f, -0.5f, 0.f), + glm::vec3(0.5f, -0.5f, 0.f), + glm::vec3(0.f, 0.5f, 0.f), + }; */ + /* std::vector vertices = { + glm::vec3(0.5f, 0.5f, 0.0f), + glm::vec3(0.5f, -0.5f, 0.0f), + glm::vec3(-0.5f, 0.5f, 0.0f), + }; + + std::shared_ptr tri(new simpleengine::shapes_2d::Triangle(base_shader_program, vertices)); + game.add_event(tri); */ + + /* 0.5f, 0.5f, 0.0f, // top right + 0.5f, -0.5f, 0.0f, // bottom right + -0.5f, 0.5f, 0.0f, // top left + // second triangle + 0.5f, -0.5f, 0.0f, // bottom right + -0.5f, -0.5f, 0.0f, // bottom left + -0.5f, 0.5f, 0.0f */ + + std::vector vertices = { + glm::vec3(0.5f, 0.5f, 0.f), // top right + glm::vec3(0.5f, -0.5f, 0.f), // bottom right + glm::vec3(-0.5f, -0.5f, 0.f), // bottom left + glm::vec3(-0.5f, 0.5f, 0.f), // top left + }; + + std::vector indicies = { + 0, 1, 3, // first triangle + 1, 2, 3 // second triangle + }; + + std::shared_ptr square(new simpleengine::shapes_2d::Square(base_shader_program, vertices, indicies)); + game.add_event(square); return game.run(); } \ No newline at end of file diff --git a/include/simpleengine/gfx/vao.h b/include/simpleengine/gfx/vao.h new file mode 100644 index 0000000..7fdb154 --- /dev/null +++ b/include/simpleengine/gfx/vao.h @@ -0,0 +1,82 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// + +#ifndef SIMPLEENGINE_VAO_H +#define SIMPLEENGINE_VAO_H + +#include +#include + +#include "vbo.h" + +namespace simpleengine::gfx { + class VAO { + public: + GLuint handle; + + VAO() { + glGenVertexArrays(1, &handle); + } + + ~VAO() { + destroy(); + } + + void destroy() { + glDeleteVertexArrays(1, &handle); + } + + void bind() { + glBindVertexArray(handle); + } + + void attr(VBO vbo) { + bind(); + vbo.bind(); + + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); + glEnableVertexAttribArray(0); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); + } + + void enable_attrib(VBO vbo, GLuint index, GLint size, GLenum type, GLsizei stride, size_t offset) { + bind(); + vbo.bind(); + + // NOTE: glVertexAttribPointer will AUTO-CONVERT integer values to floating point. + // Integer vertex attributes must be specified with glVertexAttribIPointer. + // THIS IS EVIL. OpenGL is bad. Who designed this to fail silently? + switch (type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_INT: + case GL_UNSIGNED_INT: + case GL_INT_2_10_10_10_REV: + case GL_UNSIGNED_INT_2_10_10_10_REV: + glVertexAttribIPointer(index, size, type, stride, (void *) offset); + break; + default: + glVertexAttribPointer(index, size, type, GL_FALSE, stride, (void *) 0); + break; + } + 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); + + // 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); + } + }; +} + +#endif \ No newline at end of file diff --git a/include/simpleengine/gfx/vbo.h b/include/simpleengine/gfx/vbo.h new file mode 100644 index 0000000..807b5a0 --- /dev/null +++ b/include/simpleengine/gfx/vbo.h @@ -0,0 +1,42 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// + +#ifndef SIMPLEENGINE_VBO_H +#define SIMPLEENGINE_VBO_H + +#include +#include + +namespace simpleengine::gfx { + class VBO { + public: + GLuint handle; + GLint type; + bool dynamic; + + VBO(GLint type, bool dynamic) : type(type), dynamic(dynamic) { + glGenBuffers(1, &handle); + } + + ~VBO() { + destroy(); + } + + void destroy() { + glDeleteBuffers(1, &handle); + } + + void bind() { + glBindBuffer(type, handle); + } + + void buffer(void *data, size_t offset, size_t count) { + bind(); + glBufferData(type, count - offset, data, dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); + } + }; +} + +#endif \ No newline at end of file diff --git a/include/simpleengine/shader.h b/include/simpleengine/shader.h index c82145a..8c26f66 100644 --- a/include/simpleengine/shader.h +++ b/include/simpleengine/shader.h @@ -17,21 +17,22 @@ #include #include #include +#include #include #include #include namespace simpleengine { - class ShaderException : public std::exception { + class ShaderException : public std::runtime_error { public: - explicit ShaderException(char const* const msg) : std::exception(msg) { + explicit ShaderException(char const* const msg) : std::runtime_error(msg) { } }; enum ShaderType { - Vertex = GL_VERTEX_SHADER, - Fragment = GL_FRAGMENT_SHADER, + ST_Vertex = GL_VERTEX_SHADER, + ST_Fragment = GL_FRAGMENT_SHADER, }; class Shader : public simpleengine::Event { diff --git a/include/simpleengine/shader_program.h b/include/simpleengine/shader_program.h index e99a864..032f316 100644 --- a/include/simpleengine/shader_program.h +++ b/include/simpleengine/shader_program.h @@ -44,7 +44,7 @@ namespace simpleengine { */ ShaderProgram& add_shader(Shader& shader) { if (shader.program != this->program) { - throw std::exception("The added shader does not have the same program as this shade program!"); + throw std::runtime_error("The added shader does not have the same program as this shade program!"); } shaders.push_back(shader); @@ -88,7 +88,7 @@ namespace simpleengine { */ void link() { if (shaders.empty()) { - throw std::exception("Shaders cannot be empty when running simpleengine::ShaderProgram::link()!"); + throw std::runtime_error("Shaders cannot be empty when running simpleengine::ShaderProgram::link()!"); } glLinkProgram(*program); diff --git a/include/simpleengine/shapes/2d/square.h b/include/simpleengine/shapes/2d/square.h new file mode 100644 index 0000000..9e60fd1 --- /dev/null +++ b/include/simpleengine/shapes/2d/square.h @@ -0,0 +1,67 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// + +#ifndef SIMPLEENGINE_SQUARE_H +#define SIMPLEENGINE_SQUARE_H + +#include +#include + +#include + +#include + +#include "../../renderable.h" +#include "../../vertex.h" + +#include "../../gfx/vbo.h" +#include "../../gfx/vao.h" +#include "simpleengine/gfx/vao.h" + +#include +#include + +namespace simpleengine::shapes_2d { + class Square : public simpleengine::Renderable { + private: + using super = simpleengine::Renderable; + private: + std::shared_ptr shader_program; + public: + std::vector vertices; + std::vector indicies; + gfx::VBO ebo; + gfx::VBO vbo; + gfx::VAO vao; + + Square(std::shared_ptr shader_program, std::vector vertices, std::vector indicies) : + super(nullptr), shader_program(shader_program), vertices(vertices), indicies(indicies), + ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)), + vao(gfx::VAO()) { + + vao.bind(); + vbo.buffer(vertices.data(), 0, vertices.size() * sizeof(float) * 3); + ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); + + // idfk why its 3 + vao.enable_attrib(ebo, 0, 3, GL_FLOAT, 3 * sizeof(float), 0); + } + + virtual ~Square() = default; + + virtual void update(const float& delta_time) override { + + } + + virtual void render(std::shared_ptr target) override { + glUseProgram(*shader_program); + + vao.bind(); + glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0); + } + }; +} + +#endif //SIMPLEENGINE_TRIANGLE_H \ No newline at end of file diff --git a/include/simpleengine/shapes/2d/triangle.h b/include/simpleengine/shapes/2d/triangle.h index b3a3a00..8a71dac 100644 --- a/include/simpleengine/shapes/2d/triangle.h +++ b/include/simpleengine/shapes/2d/triangle.h @@ -11,7 +11,16 @@ #include +#include + #include "../../renderable.h" +#include "../../vertex.h" + +#include "../../gfx/vbo.h" +#include "../../gfx/vao.h" +#include "simpleengine/gfx/vao.h" + +#include namespace simpleengine::shapes_2d { class Triangle : public simpleengine::Renderable { @@ -20,33 +29,17 @@ namespace simpleengine::shapes_2d { private: std::shared_ptr shader_program; public: - float vertices[9]; - uint32_t vbo; - uint32_t vao; + std::vector vertices; + gfx::VBO vbo; + gfx::VAO vao; - Triangle(std::shared_ptr shader_program) : super(nullptr), shader_program(shader_program), vertices{ - -0.5f, -0.5f, 0.0f, // left - 0.5f, -0.5f, 0.0f, // right - 0.0f, 0.5f, 0.0f // top - } { - - glGenVertexArrays(1, &vao); - glGenBuffers(1, &vbo); - // bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s). - glBindVertexArray(vao); + Triangle(std::shared_ptr shader_program, std::vector vertices) : super(nullptr), + shader_program(shader_program), vertices(vertices), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)), + vao(gfx::VAO()) { - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); - glEnableVertexAttribArray(0); - - // 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); + vao.bind(); + vbo.buffer(vertices.data(), 0, vertices.size() * sizeof(float) * 3); // 3 floats are in each "row" of the vector. + vao.enable_attrib(vbo, 0, vertices.size(), GL_FLOAT, 3 * sizeof(float), 0); } virtual ~Triangle() = default; @@ -57,7 +50,8 @@ namespace simpleengine::shapes_2d { virtual void render(std::shared_ptr target) override { glUseProgram(*shader_program); - glBindVertexArray(vao); + + vao.bind(); glDrawArrays(GL_TRIANGLES, 0, 3); } }; diff --git a/include/simpleengine/vertex.h b/include/simpleengine/vertex.h new file mode 100644 index 0000000..85b8702 --- /dev/null +++ b/include/simpleengine/vertex.h @@ -0,0 +1,23 @@ +// +// Created by SeanOMik on 7/2/2020. +// Github: https://github.com/SeanOMik +// + +#ifndef SIMPLEENGINE_VERTEX_H +#define SIMPLEENGINE_VERTEX_H + +#include +#include + +#include + +namespace simpleengine { + class Vertex { + public: + glm::vec3 position; + glm::vec3 color; + glm::vec2 tex_coord; + }; +} + +#endif //SIMPLEENGINE_VERTEX_H \ No newline at end of file