From 649c187dd4d0598975916fcf7b1b40a02d122b7a Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Sat, 17 Jul 2021 17:34:02 +0100 Subject: [PATCH] Add cube + planes to mesh generator. * The planes and cube are from first priciples so probably don't follow best practice with regards to ordering * Renderer includes some matrixes for testing (spin objects, fixed prespective) * Model renderer uses backface culling (to check winding order of polygons --- demo/data/unlit_vert.glsl | 6 ++- demo/main.cpp | 5 +- fggl/data/procedural.cpp | 102 ++++++++++++++++++++++++++++++++++++++ fggl/data/procedural.hpp | 12 ++++- fggl/gfx/ogl.cpp | 2 + fggl/gfx/renderer.cpp | 26 +++++++++- fggl/gfx/renderer.hpp | 4 +- fggl/gfx/window.cpp | 5 ++ 8 files changed, 155 insertions(+), 7 deletions(-) diff --git a/demo/data/unlit_vert.glsl b/demo/data/unlit_vert.glsl index c74ea10..fffe16c 100644 --- a/demo/data/unlit_vert.glsl +++ b/demo/data/unlit_vert.glsl @@ -1,7 +1,11 @@ #version 330 core layout (location = 0) in vec3 aPos; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; + void main() { - gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); + gl_Position = projection * view * model * vec4(aPos, 1.0f); } diff --git a/demo/main.cpp b/demo/main.cpp index 4c73b34..1ea5234 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -69,7 +69,8 @@ int main(int argc, char* argv[]) { auto entity = ecs.createEntity(); // in a supprise to no one it's a triangle - auto mesh = fggl::data::make_triangle(); +// auto mesh = fggl::data::make_quad_xy(); + auto mesh = fggl::data::make_cube(); auto token = meshRenderer.upload(mesh); token.pipeline = shader; ecs.addComponent<fggl::gfx::MeshToken>(entity, token); @@ -82,7 +83,7 @@ int main(int argc, char* argv[]) { // render step ogl.clear(); - meshRenderer.render(win, ecs); + meshRenderer.render(win, ecs, 16.0f); debug.draw(); win.swap(); diff --git a/fggl/data/procedural.cpp b/fggl/data/procedural.cpp index b762adc..0a5f5d8 100644 --- a/fggl/data/procedural.cpp +++ b/fggl/data/procedural.cpp @@ -28,6 +28,108 @@ fggl::data::Mesh fggl::data::make_triangle() { return mesh; } +fggl::data::Mesh fggl::data::make_quad_xy() { + constexpr fggl::math::vec3 pos[] { + {-0.5f, -0.5f, 0.0f}, + { 0.5f, -0.5f, 0.0f}, + { 0.5f, 0.5f, 0.0f}, + {-0.5f, 0.5f, 0.0f} + }; + constexpr int idx[] { + 0, 1, 3, + 3, 1, 2 + }; + + fggl::data::Mesh mesh; + int colIdx[4]; + for (int i = 0; i < 4; ++i){ + Vertex vert{}; + vert.posititon = pos[i]; + vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); + colIdx[ i ] = mesh.pushVertex(vert); + } + + for( auto i : idx ) { + mesh.pushIndex( colIdx[ i ] ); + } + + return mesh; +} + +fggl::data::Mesh fggl::data::make_quad_xz() { + constexpr fggl::math::vec3 pos[] { + {-0.5f, 0.0f, -0.5f}, + { 0.5f, 0.0f, -0.5f}, + { 0.5f, 0.0f, 0.5f}, + {-0.5f, 0.0f, 0.5f} + }; + constexpr int idx[] { + 0, 1, 3, + 3, 1, 2 + }; + + fggl::data::Mesh mesh; + int colIdx[4]; + for (int i = 0; i < 4; ++i){ + Vertex vert{}; + vert.posititon = pos[i]; + vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); + colIdx[ i ] = mesh.pushVertex(vert); + } + + for( auto i : idx ) { + mesh.pushIndex( colIdx[ i ] ); + } + + return mesh; +} + + +fggl::data::Mesh fggl::data::make_cube() { + + // done as two loops, top loop is 0,1,2,3, bottom loop is 4,5,6,7 + constexpr fggl::math::vec3 pos[] { + {-0.5, 0.5, -0.5}, // 0 TOP LOOP + { 0.5, 0.5, -0.5}, // 1 + { 0.5, 0.5, 0.5}, // 2 + {-0.5, 0.5, 0.5}, // 3 + {-0.5, -0.5, -0.5}, // 4 BOTTOM LOOP + { 0.5, -0.5, -0.5}, // 5 + { 0.5, -0.5, 0.5}, // 6 + {-0.5, -0.5, 0.5} // 7 + }; + + constexpr int idx[] { + 0, 3, 1, // top + 3, 2, 1, + 0, 1, 4, // side 0 - 1 + 5, 4, 1, + 1, 2, 5, // side 1 - 2 + 2, 6, 5, + 3, 7, 2, // side 2 - 3 + 2, 7, 6, + 0, 4, 3, // side 3 - 0 + 4, 7, 3, + 4, 5, 7, // bottom + 7, 5, 6, + }; + + fggl::data::Mesh mesh; + int colIdx[8]; + for ( int i=0; i < 8; ++i ) { + Vertex vert{}; + vert.posititon = pos[i]; + vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); + colIdx[ i ] = mesh.pushVertex( vert ); + } + + for ( auto i : idx ){ + mesh.pushIndex( colIdx[i] ); + } + + return mesh; +} + /* constexpr float cubeVertex[8 * 3] = { 0, 0, 0, diff --git a/fggl/data/procedural.hpp b/fggl/data/procedural.hpp index 32b0424..4a8f183 100644 --- a/fggl/data/procedural.hpp +++ b/fggl/data/procedural.hpp @@ -3,7 +3,15 @@ namespace fggl::data { - //Mesh make_cube(); - Mesh make_triangle(); + + // quads + Mesh make_quad_xy(); + Mesh make_quad_xz(); + + // simple shapes + Mesh make_cube(); + + // blockout shapes + Mesh make_slope(); } diff --git a/fggl/gfx/ogl.cpp b/fggl/gfx/ogl.cpp index 8e84cca..7064209 100644 --- a/fggl/gfx/ogl.cpp +++ b/fggl/gfx/ogl.cpp @@ -10,6 +10,8 @@ GlGraphics::GlGraphics(Window& window) : m_window(window) { if ( GLEW_OK != err ) { throw std::runtime_error("couldn't init glew"); } + + glViewport(0, 0, 1920, 1080); } GlGraphics::~GlGraphics() { diff --git a/fggl/gfx/renderer.cpp b/fggl/gfx/renderer.cpp index 9d90911..37d93fc 100644 --- a/fggl/gfx/renderer.cpp +++ b/fggl/gfx/renderer.cpp @@ -3,6 +3,10 @@ #include <fggl/data/model.hpp> +#include <glm/ext/matrix_transform.hpp> +#include <glm/glm.hpp> +#include <glm/gtc/type_ptr.hpp> + /** * Future optimisations: * recommended approach is to group stuff in to as few vao as possible - this will do one vao per mesh, aka bad. @@ -61,20 +65,40 @@ GlRenderToken MeshRenderer::upload(fggl::data::Mesh& mesh) { return token; } -void MeshRenderer::render(const Window& window, const fggl::ecs::ECS& ecs) { +void MeshRenderer::render(const Window& window, const fggl::ecs::ECS& ecs, float dt) { auto entities = ecs.getEntityWith<GlRenderToken>(); // nothing to render, pointless doing anything else if ( entities.size() == 0) return; + glEnable(GL_CULL_FACE); + glCullFace(GL_BACK); + // make sure the correct rendering context is active window.activate(); + total += dt; + + glm::mat4 view = glm::lookAt( glm::vec3 ( 0.0f, -3.0f, 3.0f ), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f) ); + glm::mat4 proj = glm::perspective( glm::radians(45.0f), 1280.0f/720.0f, 0.1f, 100.0f); +// glm::mat4 proj = glm::mat4(1.0f); + + // TODO better performance if grouped by vao first // TODO the nvidia performance presentation said I shouldn't use uniforms for large data for ( auto& entity : entities ) { const auto& mesh = ecs.getComponent<GlRenderToken>(entity); + glm::mat4 model = glm::mat4(1.0f); + model = glm::rotate(model, glm::radians(total/2048.0f * 360.0f), glm::vec3(0.0f,1.0f,0.0f)); + + auto shader = mesh->pipeline; + glUseProgram( shader ); + + glUniformMatrix4fv( glGetUniformLocation(shader, "model"), 1, GL_FALSE, glm::value_ptr( model ) ); + glUniformMatrix4fv( glGetUniformLocation(shader, "view"), 1, GL_FALSE, glm::value_ptr( view ) ); + glUniformMatrix4fv( glGetUniformLocation(shader, "projection"), 1, GL_FALSE, glm::value_ptr( proj ) ); + glBindVertexArray( mesh->vao ); glDrawElements( GL_TRIANGLES, mesh->idxSize, GL_UNSIGNED_INT, reinterpret_cast<void*>(mesh->idxOffset) ); } diff --git a/fggl/gfx/renderer.hpp b/fggl/gfx/renderer.hpp index c8fcb60..17142aa 100644 --- a/fggl/gfx/renderer.hpp +++ b/fggl/gfx/renderer.hpp @@ -24,7 +24,9 @@ namespace fggl::gfx { token_t upload(fggl::data::Mesh& mesh); // are VAO safe across opengl contexts? :S - void render(const Window& window, const fggl::ecs::ECS& ecs); + void render(const Window& window, const fggl::ecs::ECS& ecs, float dt); + + float total; }; // specialisation hooks diff --git a/fggl/gfx/window.cpp b/fggl/gfx/window.cpp index dd27fba..0b94278 100644 --- a/fggl/gfx/window.cpp +++ b/fggl/gfx/window.cpp @@ -31,6 +31,11 @@ void Context::pollEvents() { } Window::Window() : m_window(nullptr), m_input(nullptr) { + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, true); + m_window = glfwCreateWindow(1920, 1080, "main", nullptr, nullptr); glfwSetWindowUserPointer(m_window, this); } -- GitLab