From 283df10f868a3f6dc18dbd8fa67d10b1002ca921 Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Thu, 14 Dec 2023 11:20:14 -0600
Subject: [PATCH] Flip Y coordinates on textures on UIShader

---
 src/dawn/component/ui/UICanvas.cpp            |  2 +-
 src/dawn/display/shader/CMakeLists.txt        |  1 +
 src/dawn/display/shader/IShader.cpp           | 46 ++++++++++++++++
 src/dawn/display/shader/IShader.hpp           | 10 +++-
 src/dawn/ui/UILabel.cpp                       |  2 +-
 src/dawnhelloworld/scene/HelloWorldScene.cpp  |  7 ++-
 .../display/shader/ShaderStructure.hpp        | 42 +++++++++------
 src/dawnopengl/display/shader/UIShader.cpp    | 53 ++++++++++---------
 src/dawnopengl/display/shader/UIShader.hpp    |  1 +
 9 files changed, 120 insertions(+), 44 deletions(-)
 create mode 100644 src/dawn/display/shader/IShader.cpp

diff --git a/src/dawn/component/ui/UICanvas.cpp b/src/dawn/component/ui/UICanvas.cpp
index 917b7564..2d324dd8 100644
--- a/src/dawn/component/ui/UICanvas.cpp
+++ b/src/dawn/component/ui/UICanvas.cpp
@@ -66,7 +66,7 @@ void UICanvas::addQuad(
   const struct Color color,
   const std::shared_ptr<Texture> text
 ) {
-  float_t fTexture = -1;
+  float_t fTexture;
   if(text == nullptr) {
     fTexture = -1;
   } else {
diff --git a/src/dawn/display/shader/CMakeLists.txt b/src/dawn/display/shader/CMakeLists.txt
index c1917ed1..1d4aa6a9 100644
--- a/src/dawn/display/shader/CMakeLists.txt
+++ b/src/dawn/display/shader/CMakeLists.txt
@@ -6,5 +6,6 @@
 # Sources
 target_sources(${DAWN_TARGET_NAME}
   PRIVATE
+    IShader.cpp
     IShaderStage.cpp
 )
\ No newline at end of file
diff --git a/src/dawn/display/shader/IShader.cpp b/src/dawn/display/shader/IShader.cpp
new file mode 100644
index 00000000..941406b1
--- /dev/null
+++ b/src/dawn/display/shader/IShader.cpp
@@ -0,0 +1,46 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "display/shader/Shader.hpp"
+#include "assert/assert.hpp"
+#include "display/Color.hpp"
+#include "display/Texture.hpp"
+
+using namespace Dawn;
+
+size_t shaderParameterTypeGetSize(const enum ShaderParameterType type) {
+  switch(type) {
+    case ShaderParameterType::VEC2:
+      return sizeof(glm::vec2);
+
+    case ShaderParameterType::VEC3:
+      return sizeof(glm::vec3);
+
+    case ShaderParameterType::VEC4:
+      return sizeof(glm::vec4);
+
+    case ShaderParameterType::MAT3:
+      return sizeof(glm::mat3);
+
+    case ShaderParameterType::MAT4:
+      return sizeof(glm::mat4);
+
+    case ShaderParameterType::COLOR:
+      return sizeof(struct Color);
+
+    case ShaderParameterType::FLOAT:
+      return sizeof(float);
+
+    case ShaderParameterType::INT:
+      return sizeof(int32_t);
+
+    case ShaderParameterType::TEXTURE:
+      return sizeof(shadertexturebinding_t);
+
+    default:
+      assertUnreachable("Unknown ShaderParameterType");
+      return 0;
+  }
+}
diff --git a/src/dawn/display/shader/IShader.hpp b/src/dawn/display/shader/IShader.hpp
index b19421e0..b35aadd5 100644
--- a/src/dawn/display/shader/IShader.hpp
+++ b/src/dawn/display/shader/IShader.hpp
@@ -75,4 +75,12 @@ namespace Dawn {
         
       }
   };
-}
\ No newline at end of file
+}
+
+/**
+ * Returns the size of the ShaderParameterType.
+ * 
+ * @param type The type to get the size of.
+ * @return Size of the type.
+ */
+size_t shaderParameterTypeGetSize(const enum Dawn::ShaderParameterType type);
\ No newline at end of file
diff --git a/src/dawn/ui/UILabel.cpp b/src/dawn/ui/UILabel.cpp
index dc079ca7..bf3de4a7 100644
--- a/src/dawn/ui/UILabel.cpp
+++ b/src/dawn/ui/UILabel.cpp
@@ -11,7 +11,7 @@ void UILabel::getSelfQuads(const glm::vec2 t, UICanvas &ctx) {
   std::vector<struct UIShaderQuad> quads;
   if(this->texture == nullptr) return;
 
-  const std::wstring text = L"He";
+  const std::wstring text = L"Hello World";
   glm::vec2 position = t;
   glm::vec4 quad;
 
diff --git a/src/dawnhelloworld/scene/HelloWorldScene.cpp b/src/dawnhelloworld/scene/HelloWorldScene.cpp
index 255f6758..22fb6cfc 100644
--- a/src/dawnhelloworld/scene/HelloWorldScene.cpp
+++ b/src/dawnhelloworld/scene/HelloWorldScene.cpp
@@ -22,7 +22,7 @@ using namespace Dawn;
 std::shared_ptr<TrueTypeTexture> texture;
 
 void Dawn::helloWorldScene(Scene &s) {
-  texture = s.getGame()->assetManager.get<TrueTypeTexture>("ysabeau_regular", 16);
+  texture = s.getGame()->assetManager.get<TrueTypeTexture>("ysabeau_regular", 32);
 
   while(!s.getGame()->assetManager.isLoaded("ysabeau_regular")) {
     s.getGame()->assetManager.update();
@@ -54,9 +54,14 @@ void Dawn::helloWorldScene(Scene &s) {
 
   // auto rect = std::make_shared<UIRectangle>();
   // rect->position = { -32, -32 };
+  // rect->size = { 8, 8 };
   // rect->color = COLOR_MAGENTA;
   // uiCanvas->components.push_back(rect);
 
+  // auto rect2 = std::make_shared<UIRectangle>();
+  // rect2->color = COLOR_BLUE;
+  // uiCanvas->components.push_back(rect2);
+
   auto label = std::make_shared<UILabel>();
   label->setFont(texture);
   uiCanvas->components.push_back(label);
diff --git a/src/dawnopengl/display/shader/ShaderStructure.hpp b/src/dawnopengl/display/shader/ShaderStructure.hpp
index dc672560..b384aea5 100644
--- a/src/dawnopengl/display/shader/ShaderStructure.hpp
+++ b/src/dawnopengl/display/shader/ShaderStructure.hpp
@@ -60,24 +60,36 @@ namespace Dawn {
         getParameters(dummy, this->parameters);
 
         // Update offsets.
-        std::for_each(
-          this->parameters.begin(),
-          this->parameters.end(),
-          [&](struct ShaderParameter &param) {
-            param.offset -= (size_t)(&dummy);
+        auto itParams = this->parameters.begin();
+        while(itParams != this->parameters.end()) {
+          struct ShaderParameter &param = *itParams;
+          param.offset -= (size_t)(&dummy);
 
-            // Check for non-aligned OpenGL structures.
-            if(param.offset % sizeof(glm::vec4) != 0) {
-              assertUnreachable(
-                "%s%s%s",
-                "Non-aligned OpenGL structure detected on param ",
-                param.name.c_str(),
-                "!\nEnsure you have padded correctly."
-              );
-            }
+          // Check for non-aligned OpenGL structures.
+          if(param.offset % sizeof(glm::vec4) != 0) {
+            assertUnreachable(
+              "%s%s%s",
+              "Non-aligned OpenGL structure detected on param ",
+              param.name.c_str(),
+              "!\nEnsure you have padded correctly."
+            );
           }
-        );
 
+          if(
+            itParams == (this->parameters.end() - 1) &&
+            count > 1 &&
+            (sizeof(T) % sizeof(glm::vec4)) != 0
+          ) {
+            assertUnreachable(
+              "%s%s%s",
+              "Non-aligned OpenGL structure detected on last element in array structure on param ",
+              param.name.c_str(),
+              "!\nEnsure you have padded correctly."
+            );
+          }
+
+          ++itParams;
+        }
       }
   };
 }
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/UIShader.cpp b/src/dawnopengl/display/shader/UIShader.cpp
index 600a3c06..fe13477b 100644
--- a/src/dawnopengl/display/shader/UIShader.cpp
+++ b/src/dawnopengl/display/shader/UIShader.cpp
@@ -52,22 +52,22 @@ void UIShader::getStages(
             "pos.x = quad.quad.x;\n"
             "pos.y = quad.quad.y;\n"
             "coord.x = quad.uv.x;\n"
-            "coord.y = quad.uv.y;\n"
+            "coord.y = quad.uv.w;\n"
           "} else if(vertexIndex == 1) {\n"
             "pos.x = quad.quad.z;\n"
             "pos.y = quad.quad.y;\n"
             "coord.x = quad.uv.z;\n"
-            "coord.y = quad.uv.y;\n"
+            "coord.y = quad.uv.w;\n"
           "} else if(vertexIndex == 2) {\n"
             "pos.y = quad.quad.w;\n"
             "pos.x = quad.quad.x;\n"
             "coord.x = quad.uv.x;\n"
-            "coord.y = quad.uv.w;\n"
+            "coord.y = quad.uv.y;\n"
           "} else if(vertexIndex == 3) {\n"
             "pos.x = quad.quad.z;\n"
             "pos.y = quad.quad.w;\n"
             "coord.x = quad.uv.z;\n"
-            "coord.y = quad.uv.w;\n"
+            "coord.y = quad.uv.y;\n"
           "}\n"
           "pos.z = 0;\n"
           "pos.w = 1;\n"
@@ -88,27 +88,30 @@ void UIShader::getStages(
         "out vec4 o_Color;\n" 
         "void main() {\n"
           "vec4 texColor = vec4(1, 1, 1, 1);\n"
-          // "switch(int(v_TextureIndex)) {\n"
-          //   "case 0:\n"
-          //     "texColor = texture(u_Texture[0], v_TextCoord);\n"
-          //     "break;\n"
-          //   "case 1:\n"
-          //     "texColor = texture(u_Texture[1], v_TextCoord);\n"
-          //     "break;\n"
-          //   "case 2:\n"
-          //     "texColor = texture(u_Texture[2], v_TextCoord);\n"
-          //     "break;\n"
-          //   "case 3:\n"
-          //     "texColor = texture(u_Texture[3], v_TextCoord);\n"
-          //     "break;\n"
-          //   "case 4:\n"
-          //     "texColor = texture(u_Texture[4], v_TextCoord);\n"
-          //     "break;\n"
-          //   "case 5:\n"
-          //     "texColor = texture(u_Texture[5], v_TextCoord);\n"
-          //     "break;\n"
-          // "}\n"
-          "texColor = texture(u_Texture[0], v_TextCoord);\n"
+          "int vTextInd = int(round(v_TextureIndex));\n"
+          "switch(vTextInd) {\n"
+            "case -1:\n"
+              "texColor = vec4(1, 1, 1, 1);\n"
+              "break;\n"
+            "case 0:\n"
+              "texColor = texture(u_Texture[0], v_TextCoord);\n"
+              "break;\n"
+            "case 1:\n"
+              "texColor = texture(u_Texture[1], v_TextCoord);\n"
+              "break;\n"
+            "case 2:\n"
+              "texColor = texture(u_Texture[2], v_TextCoord);\n"
+              "break;\n"
+            "case 3:\n"
+              "texColor = texture(u_Texture[3], v_TextCoord);\n"
+              "break;\n"
+            "case 4:\n"
+              "texColor = texture(u_Texture[4], v_TextCoord);\n"
+              "break;\n"
+            "case 5:\n"
+              "texColor = texture(u_Texture[5], v_TextCoord);\n"
+              "break;\n"
+          "}\n"
           "o_Color = texColor * v_Color;\n"
         "}\n"
       );
diff --git a/src/dawnopengl/display/shader/UIShader.hpp b/src/dawnopengl/display/shader/UIShader.hpp
index f5013748..29ad39b7 100644
--- a/src/dawnopengl/display/shader/UIShader.hpp
+++ b/src/dawnopengl/display/shader/UIShader.hpp
@@ -15,6 +15,7 @@ namespace Dawn {
     glm::vec4 uv;
     struct Color color;
     float_t texture;
+    glm::vec3 padding;
   };
   
   struct UIShaderData {