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