From fb2f2bd19a4c112f0a2368b6e1ab5b21c9587838 Mon Sep 17 00:00:00 2001
From: Joseph Walton-Rivers <joseph@walton-rivers.uk>
Date: Sat, 22 Oct 2022 20:45:35 +0100
Subject: [PATCH] inject texture into rendering pipeline

---
 demo/data/redbook/debug_frag.glsl  |  5 ++-
 demo/data/redbook/debug_vert.glsl  |  5 ++-
 fggl/data/assimp/module.cpp        |  8 +++--
 fggl/gfx/ogl/renderer.cpp          | 57 +++++++++++++++++++++++++++---
 fggl/gfx/ogl4/meshes.cpp           |  2 +-
 fggl/gfx/ogl4/models.cpp           |  4 +--
 fggl/gfx/ogl4/module.cpp           |  2 --
 include/fggl/assets/manager.hpp    |  1 +
 include/fggl/gfx/ogl/types.hpp     | 56 +++++++++++++++--------------
 include/fggl/gfx/ogl4/fallback.hpp |  4 +++
 include/fggl/gfx/ogl4/meshes.hpp   | 13 ++++++-
 include/fggl/mesh/mesh.hpp         |  2 +-
 12 files changed, 117 insertions(+), 42 deletions(-)

diff --git a/demo/data/redbook/debug_frag.glsl b/demo/data/redbook/debug_frag.glsl
index aa8e88c..299da0c 100644
--- a/demo/data/redbook/debug_frag.glsl
+++ b/demo/data/redbook/debug_frag.glsl
@@ -7,10 +7,13 @@
 in vec4 Position;
 in vec3 Normal;
 in vec4 Colour;
+in vec2 TexPos;
 
 out vec4 FragColour;
 
+uniform sampler2D diffuseTexture;
+
 void main() {
     vec3 normalScale = 0.5 + (Normal / 2);
-    FragColour = Colour * vec4(normalScale, 1);
+    FragColour = Colour * vec4(normalScale, 1) * texture(diffuseTexture, TexPos);
 }
\ No newline at end of file
diff --git a/demo/data/redbook/debug_vert.glsl b/demo/data/redbook/debug_vert.glsl
index 02d3cd9..cf0e341 100644
--- a/demo/data/redbook/debug_vert.glsl
+++ b/demo/data/redbook/debug_vert.glsl
@@ -7,6 +7,7 @@
 layout (location = 0) in vec3 VertexPosition;
 layout (location = 1) in vec3 VertexNormal;
 layout (location = 2) in vec3 VertexColour;
+layout (location = 3) in vec2 VertexTex;
 
 uniform mat4 MVPMatrix;
 uniform mat4 MVMatrix;
@@ -15,10 +16,12 @@ uniform mat3 NormalMatrix;
 out vec4 Position;
 out vec3 Normal;
 out vec4 Colour;
+out vec2 TexPos;
 
 void main() {
-    Colour = vec4(0.5, 0.5, 0.5, 1.0f);
+    Colour = vec4(VertexColour, 1);
     Normal = NormalMatrix * VertexNormal;
+    TexPos = VertexTex;
     Position = MVMatrix * vec4(VertexPosition, 1);
     gl_Position = MVPMatrix * vec4(VertexPosition, 1);
 }
\ No newline at end of file
diff --git a/fggl/data/assimp/module.cpp b/fggl/data/assimp/module.cpp
index 99d2a63..f97a94b 100644
--- a/fggl/data/assimp/module.cpp
+++ b/fggl/data/assimp/module.cpp
@@ -32,7 +32,11 @@ namespace fggl::data::models {
 		return {vec.x, vec.y, vec.z};
 	}
 
-	constexpr math::vec2 convert(aiVector2D& vec) {
+	constexpr math::vec2 convert2(aiVector2D& vec) {
+		return {vec.x, vec.y};
+	}
+
+	constexpr math::vec2 convert2(aiVector3D& vec) {
 		return {vec.x, vec.y};
 	}
 
@@ -47,7 +51,7 @@ namespace fggl::data::models {
 			};
 
 			if ( assimpMesh->mTextureCoords[0] != nullptr ) {
-				vertex.texPos = convert( assimpMesh->mTextureCoords[0][idx] );
+				vertex.texPos = convert2( assimpMesh->mTextureCoords[0][idx] );
 			}
 
 			mesh.data.push_back(vertex);
diff --git a/fggl/gfx/ogl/renderer.cpp b/fggl/gfx/ogl/renderer.cpp
index c13ef6c..f0a4bb0 100644
--- a/fggl/gfx/ogl/renderer.cpp
+++ b/fggl/gfx/ogl/renderer.cpp
@@ -139,6 +139,55 @@ namespace fggl::gfx {
 	using data::Mesh2D;
 	using data::Vertex2D;
 
+	static void setup_shaders(ShaderCache* cache) {
+		// FIXME this should not be hard-coded, it should be part of the scene loading process
+		cache->load(ShaderConfig::named("phong"));
+		cache->load(ShaderConfig::named("redbook/lighting"));
+		cache->load(ShaderConfig::named("redbook/debug"));
+
+		// debug shaders
+		cache->load(ShaderConfig::named("normals", true));
+		cache->load(ShaderConfig::named("debug"));
+	}
+
+	static void splat_checkerboard(GLuint* memory) {
+		for (int i = 0; i < 128 * 128; ++i) {
+			GLubyte* colours = (GLubyte*)&memory[i];
+			if( i / 128 & 16 ^ i % 128 & 16 )
+        	{
+            	//Set pixel to white
+	            colours[ 0 ] = 0xFF;
+    	        colours[ 1 ] = 0xFF;
+        	    colours[ 2 ] = 0xFF;
+            	colours[ 3 ] = 0xFF;
+	        }
+    	    else
+       	 	{
+        	    //Set pixel to red
+           		colours[ 0 ] = 0xFF;
+            	colours[ 1 ] = 0x00;
+            	colours[ 2 ] = 0x00;
+            	colours[ 3 ] = 0xFF;
+        	}
+		}
+	}
+
+	static void setup_fallback_texture(assets::AssetManager* assets) {
+		auto* fallback2D = new ogl::Texture(ogl::TextureType::Tex2D);
+
+		GLuint myData[128 * 128];
+		splat_checkerboard(myData);
+
+		ogl::Image image{
+			.type = ogl::PixelFormat::UNSIGNED_BYTE,
+			.format = ogl::ImageFormat::RGBA,
+			.size = {128, 128},
+			.data = myData
+		};
+		fallback2D->setData(ogl::InternalImageFormat::RedGreenBlueAlpha, image);
+		assets->set(ogl4::FALLBACK_TEX, fallback2D);
+	}
+
 	OpenGL4Backend::OpenGL4Backend(data::Storage *storage, gui::FontLibrary *fonts, assets::AssetManager *assets, GlFunctionLoader loader)
 		: fggl::gfx::Graphics(), m_canvasPipeline(nullptr), m_storage(storage) {
 
@@ -166,6 +215,7 @@ namespace fggl::gfx {
 
 		// setup the shader cache
 		m_cache = std::make_unique<ShaderCache>(m_storage);
+		setup_shaders(m_cache.get());
 
 		// setup 2D rendering system
 		ShaderConfig shader2DConfig = ShaderConfig::named("canvas");
@@ -175,11 +225,8 @@ namespace fggl::gfx {
 			m_canvasPipeline = m_cache->get(ogl4::FALLBACK_CANVAS_PIPELINE);
 		}
 
-		// FIXME this should not be hard-coded, it should be part of the scene loading process
-		m_cache->load(ShaderConfig::named("phong"));
-		m_cache->load(ShaderConfig::named("redbook/lighting"));
-		m_cache->load(ShaderConfig::named("redbook/debug"));
-		m_cache->load(ShaderConfig::named("normals", true));
+		// fallback textures
+		setup_fallback_texture(assets);
 
 		// rendering helpers
 		m_canvasRenderer = std::make_unique<ogl4::CanvasRenderer>(fonts);
diff --git a/fggl/gfx/ogl4/meshes.cpp b/fggl/gfx/ogl4/meshes.cpp
index 6f8fc86..94bac36 100644
--- a/fggl/gfx/ogl4/meshes.cpp
+++ b/fggl/gfx/ogl4/meshes.cpp
@@ -31,7 +31,7 @@ namespace fggl::gfx::ogl4 {
 		auto posAttr = ogl::attribute<mesh::Vertex3D, math::vec3>(offsetof(mesh::Vertex3D, position));
 		auto normalAttr = ogl::attribute<mesh::Vertex3D, math::vec3>(offsetof(mesh::Vertex3D, normal));
 		auto colAttr = ogl::attribute<mesh::Vertex3D, math::vec3>(offsetof(mesh::Vertex3D, colour));
-		auto texAttr = ogl::attribute<mesh::Vertex3D, math::vec3>(offsetof(mesh::Vertex3D, colour));
+		auto texAttr = ogl::attribute<mesh::Vertex3D, math::vec2>(offsetof(mesh::Vertex3D, texPos));
 
 		vao->setAttribute(*buff, 0, posAttr);
 		vao->setAttribute(*buff, 1, normalAttr);
diff --git a/fggl/gfx/ogl4/models.cpp b/fggl/gfx/ogl4/models.cpp
index cfe500d..1aa9c3b 100644
--- a/fggl/gfx/ogl4/models.cpp
+++ b/fggl/gfx/ogl4/models.cpp
@@ -426,8 +426,8 @@ namespace fggl::gfx::ogl4 {
 			//TODO should be clipping this to only visible objects
 			forward_camera_pass(cameraEnt, world);
 
-			forward_pass<ogl4::StaticMesh>(cameraEnt, world);
-			forward_pass<ogl4::StaticMultiMesh>(cameraEnt, world);
+			forward_pass<ogl4::StaticMesh>(cameraEnt, world, m_assets);
+			forward_pass<ogl4::StaticMultiMesh>(cameraEnt, world, m_assets);
 
 			// enable rendering normals
 			if ( debugMode ) {
diff --git a/fggl/gfx/ogl4/module.cpp b/fggl/gfx/ogl4/module.cpp
index e18cce7..e4bb673 100644
--- a/fggl/gfx/ogl4/module.cpp
+++ b/fggl/gfx/ogl4/module.cpp
@@ -155,10 +155,8 @@ namespace fggl::gfx {
 			// register as responsible for creating rendering components
 			auto *entityFactory = services.get<entity::EntityFactory>();
 			entityFactory->bind(data::StaticMesh::guid, attach_mesh);
-
 			entityFactory->bind(mesh::StaticMesh3D::guid, attach_mesh);
 			entityFactory->bind(mesh::StaticMultiMesh3D::guid, attach_mesh);
-
 			entityFactory->bind(gfx::PhongMaterial::guid, attach_material);
 			entityFactory->bind(gfx::Light::guid, attach_light);
 
diff --git a/include/fggl/assets/manager.hpp b/include/fggl/assets/manager.hpp
index 27a9fc9..481a252 100644
--- a/include/fggl/assets/manager.hpp
+++ b/include/fggl/assets/manager.hpp
@@ -27,6 +27,7 @@
 #include "fggl/debug/logging.hpp"
 #include "fggl/assets/types.hpp"
 #include "fggl/util/safety.hpp"
+#include "fggl/modules/module.hpp"
 
 namespace fggl::assets {
 
diff --git a/include/fggl/gfx/ogl/types.hpp b/include/fggl/gfx/ogl/types.hpp
index 6f070c7..4478b17 100644
--- a/include/fggl/gfx/ogl/types.hpp
+++ b/include/fggl/gfx/ogl/types.hpp
@@ -172,14 +172,14 @@ namespace fggl::gfx::ogl {
 
 	enum class PixelFormat {
 		UNSIGNED_BYTE = GL_UNSIGNED_BYTE,
-		BYTE,
-		UNSIGNED_SHORT,
-		SHORT,
-		UNSIGNED_INT,
-		INT,
-		HALF_FLOAT,
-		FLOAT,
-
+		BYTE = GL_BYTE,
+		UNSIGNED_SHORT = GL_UNSIGNED_SHORT,
+		SHORT = GL_SHORT,
+		UNSIGNED_INT = GL_UNSIGNED_INT,
+		INT = GL_INT,
+		HALF_FLOAT = GL_HALF_FLOAT,
+		FLOAT = GL_FLOAT,
+/*
 		UNSIGNED_BYTE_3_3_2,
 		UNSIGNED_BYTE_2_3_3_REV,
 		UNSIGNED_SHORT_5_6_5,
@@ -191,7 +191,7 @@ namespace fggl::gfx::ogl {
 		UNSIGNED_INT_8_8_8_8,
 		UNSIGNED_INT_8_8_8_8_REV,
 		UNSIGNED_INT_10_10_10_10_2,
-		UNSIGNED_INT_10_10_10_10_2_REV,
+		UNSIGNED_INT_10_10_10_10_2_REV,*/
 	};
 
 	enum class InternalImageFormat {
@@ -205,20 +205,20 @@ namespace fggl::gfx::ogl {
 
 	enum class ImageFormat {
 		R = GL_RED,
-		RG,
-		RGB,
-		RGBA,
-		R_INT,
-		RG_INT,
-		RGB_INT,
-		RGBA_INT,
-		BGR,
-		BGRA,
-		BGR_INT,
-		BGRA_INT,
-		STENTICL_INDEX,
-		DEPTH_COMPONENT,
-		DEPTH_STENCIL
+		RG = GL_RG,
+		RGB = GL_RGB,
+		RGBA = GL_RGBA,
+		R_INT = GL_RED_INTEGER,
+		RG_INT = GL_RG_INTEGER,
+		RGB_INT = GL_RGB_INTEGER,
+		RGBA_INT = GL_RGBA_INTEGER,
+		BGR = GL_BGR,
+		BGRA = GL_BGRA,
+		BGR_INT = GL_BGR_INTEGER,
+		BGRA_INT = GL_BGRA_INTEGER,
+		STENTICL_INDEX = GL_STENCIL_INDEX,
+		DEPTH_COMPONENT = GL_DEPTH_COMPONENT,
+		DEPTH_STENCIL = GL_DEPTH_STENCIL
 	};
 
 	struct Image {
@@ -242,8 +242,7 @@ namespace fggl::gfx::ogl {
 				//bind();
 				glBindTexture((GLenum) m_type, m_obj);
 				if (iFmt == InternalImageFormat::DepthComponent) {
-					glTexImage2D((GLenum)
-									 m_type,
+					glTexImage2D((GLenum)m_type,
 								 0,
 								 (GLint) iFmt,
 								 size.x,
@@ -270,6 +269,11 @@ namespace fggl::gfx::ogl {
 							 (GLenum) image.format,
 							 (GLenum) image.type,
 							 image.data);
+
+				if ( m_type == TextureType::Tex2D ) {
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+					glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+				}
 			}
 
 			void setDataPart(math::vec2i offset, Image &image) {
@@ -465,7 +469,7 @@ namespace fggl::gfx::ogl {
 		std::size_t offset;
 	};
 
-	// type intrincs to make interface nicer
+	// type intrinsics to make interface nicer
 	template<typename T>
 	struct attr_type {
 		const static BuffAttrF attr;
diff --git a/include/fggl/gfx/ogl4/fallback.hpp b/include/fggl/gfx/ogl4/fallback.hpp
index ff37beb..3d725c5 100644
--- a/include/fggl/gfx/ogl4/fallback.hpp
+++ b/include/fggl/gfx/ogl4/fallback.hpp
@@ -58,6 +58,10 @@ namespace fggl::gfx::ogl4 {
 			fragColour = vec4(colour.xyz, texture(tex, texPos).r);
 		})glsl";
 
+	constexpr const std::array<uint32_t, 4> TEX_WHITE{ 0xFF, 0xFF, 0xFF, 0xFF };
+	constexpr const std::array<uint32_t, 4> TEX_CHECKER{ 0xFF, 0x00, 0x00, 0xFF };
+	constexpr const char* FALLBACK_TEX = "FALLBACK_TEX";
+
 } // namespace fggl::gfx::ogl4
 
 #endif //FGGL_GFX_OGL4_FALLBACK_HPP
diff --git a/include/fggl/gfx/ogl4/meshes.hpp b/include/fggl/gfx/ogl4/meshes.hpp
index 6061fa4..bdc4dc8 100644
--- a/include/fggl/gfx/ogl4/meshes.hpp
+++ b/include/fggl/gfx/ogl4/meshes.hpp
@@ -21,8 +21,11 @@
 
 #include "fggl/mesh/components.hpp"
 #include "fggl/entity/entity.hpp"
+#include "fggl/assets/manager.hpp"
 
 #include "fggl/gfx/ogl/types.hpp"
+#include "fggl/gfx/ogl4/fallback.hpp"
+
 #include "fggl/gfx/camera.hpp"
 #include "fggl/gfx/phong.hpp"
 
@@ -67,7 +70,7 @@ namespace fggl::gfx::ogl4 {
 	void setup_lighting(const std::shared_ptr<ogl::Shader>& shader, const math::mat4& viewMatrix, const math::Transform& camTransform, const math::Transform& transform, math::vec3 lightPos);
 
 	template<typename T>
-	void forward_pass(const entity::EntityID& camera, const fggl::entity::EntityManager& world) {
+	void forward_pass(const entity::EntityID& camera, const fggl::entity::EntityManager& world, const assets::AssetManager* assets) {
 
 		// enable required OpenGL state
 		glEnable(GL_CULL_FACE);
@@ -76,6 +79,10 @@ namespace fggl::gfx::ogl4 {
 		// enable depth testing
 		glEnable(GL_DEPTH_TEST);
 
+		// prep the fallback textures
+		auto *fallbackTex = assets->template get<ogl::Texture>(FALLBACK_TEX);
+		fallbackTex->bind(0);
+
 		// set-up camera matrices
 		const auto &camTransform = world.get<fggl::math::Transform>(camera);
 		const auto &camComp = world.get<fggl::gfx::Camera>(camera);
@@ -112,6 +119,10 @@ namespace fggl::gfx::ogl4 {
 				}
 				mvpMatrixUniform = shader->uniform("MVPMatrix");
 				mvMatrixUniform = shader->uniform("MVMatrix");
+
+				if ( shader->hasUniform("diffuseTexture") ) {
+					shader->setUniformI(shader->uniform("diffuseTexture"), 0);
+				}
 			}
 
 			// set model transform
diff --git a/include/fggl/mesh/mesh.hpp b/include/fggl/mesh/mesh.hpp
index 8f0f898..3b0969b 100644
--- a/include/fggl/mesh/mesh.hpp
+++ b/include/fggl/mesh/mesh.hpp
@@ -30,7 +30,7 @@ namespace fggl::mesh {
 		math::vec3 position;
 		math::vec3 normal;
 		math::vec3 colour{ 1.0F, 1.0F, 1.0f };
-		math::vec2 texPos{ 0.0F, 0.0F };
+		math::vec2 texPos{ NAN, NAN };
 	};
 
 	struct Vertex2D {
-- 
GitLab