From 2dacb6f904116e549872686a27d9471160384620 Mon Sep 17 00:00:00 2001
From: Dominic Masters <dominic@domsplace.com>
Date: Thu, 19 Jan 2023 20:24:43 -0800
Subject: [PATCH] Stuff I've fixed so far.

---
 src/dawn/display/RenderPipeline.cpp           | 10 ++++-
 src/dawn/display/RenderPipeline.hpp           |  2 +-
 src/dawn/display/_RenderManager.hpp           |  8 ----
 src/dawn/display/shader/Shader.hpp            |  8 ++--
 .../scene/components/example/ExampleSpin.cpp  |  3 +-
 src/dawnopengl/display/RenderManager.cpp      |  8 +---
 src/dawnopengl/display/RenderManager.hpp      |  3 +-
 .../display/shader/SimpleTexturedShader.cpp   | 43 +++++++++++++++++++
 .../display/shader/SimpleTexturedShader.hpp   | 18 +++-----
 .../material/SimpleTexturedMaterial.cpp       |  3 +-
 .../material/SimpleTexturedMaterial.hpp       |  2 -
 .../scenes/SubSceneRendererScene.hpp          |  7 +--
 12 files changed, 72 insertions(+), 43 deletions(-)
 create mode 100644 src/dawnopengl/display/shader/SimpleTexturedShader.cpp

diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp
index 973e2770..7debf10c 100644
--- a/src/dawn/display/RenderPipeline.cpp
+++ b/src/dawn/display/RenderPipeline.cpp
@@ -78,7 +78,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
 
   // Create a new render ID. Long story short this is a really dirty way of 
   // not sending parameters to shaders more than we need.
-  this->renderId++;
+  this->renderId--;
 
   // Get the list of things to render first.
   std::vector<struct RenderPipelineItem> pipelineItems;
@@ -106,6 +106,9 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
       item.mesh = mesh;
       item.pass = *itPass;
 
+      // Validate the pass
+      assertNotNull(item.pass.shaderProgram);
+
       // Do we need to get the W Vector?
       if(item.pass.needsW) {
         assertUnreachable();// TODO: Add distance from camera for W vector.
@@ -169,13 +172,16 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
 
     // Bind the program.
     if(boundProgram != item.pass.shaderProgram) {
-      boundProgram->bind();
       boundProgram = item.pass.shaderProgram;
+      boundProgram->bind();
     }
 
     // Bind the textures to the slots
     auto itTextureSlot = item.pass.textureSlots.begin();
     while(itTextureSlot != item.pass.textureSlots.end()) {
+      // Assert texture isn't null, just don't include it.
+      assertNotNull(itTextureSlot->second);
+
       if(boundTextures[itTextureSlot->first] != itTextureSlot->second) {
         itTextureSlot->second->bind(itTextureSlot->first);
         boundTextures[itTextureSlot->first] = itTextureSlot->second;
diff --git a/src/dawn/display/RenderPipeline.hpp b/src/dawn/display/RenderPipeline.hpp
index 5c5410b1..d2c7fab0 100644
--- a/src/dawn/display/RenderPipeline.hpp
+++ b/src/dawn/display/RenderPipeline.hpp
@@ -22,7 +22,7 @@ namespace Dawn {
 
   class RenderPipeline {
     private:
-      int_fast16_t renderId;
+      int_fast16_t renderId = -1;
 
     public:
       RenderManager *renderManager;
diff --git a/src/dawn/display/_RenderManager.hpp b/src/dawn/display/_RenderManager.hpp
index 2ff5c129..d7a5601a 100644
--- a/src/dawn/display/_RenderManager.hpp
+++ b/src/dawn/display/_RenderManager.hpp
@@ -52,14 +52,6 @@ namespace Dawn {
        */
       virtual RenderPipeline * getRenderPipeline() = 0;
 
-      /**
-       * Returns the default shader, the default shader will be applied to the
-       * materials first.
-       * 
-       * @return Reference to the default shader.
-       */
-      virtual Shader * getDefaultShader() = 0;
-
       /**
        * Returns the UI Shader used by the game's UI engine.
        * 
diff --git a/src/dawn/display/shader/Shader.hpp b/src/dawn/display/shader/Shader.hpp
index 6ad78c9c..c5e7f930 100644
--- a/src/dawn/display/shader/Shader.hpp
+++ b/src/dawn/display/shader/Shader.hpp
@@ -11,9 +11,9 @@ namespace Dawn {
   class Material;
 
   struct ShaderPass {
-    ShaderProgram *shaderProgram;
-    int32_t orderShader;
-    bool_t needsW;
+    ShaderProgram *shaderProgram = nullptr;
+    int32_t orderShader = 0;
+    bool_t needsW = false;
     
     // Parameters
     std::map<shaderparameter_t, struct Color> colorValues;
@@ -29,7 +29,7 @@ namespace Dawn {
 
   class Shader {
     public:
-      int_fast16_t renderId;
+      int_fast16_t renderId = 0;
 
       /**
        * Compile all programs for this shader. This amy not remain forever as I
diff --git a/src/dawn/scene/components/example/ExampleSpin.cpp b/src/dawn/scene/components/example/ExampleSpin.cpp
index ac4f1b87..f287aab3 100644
--- a/src/dawn/scene/components/example/ExampleSpin.cpp
+++ b/src/dawn/scene/components/example/ExampleSpin.cpp
@@ -8,6 +8,7 @@
 #include "game/DawnGame.hpp"
 #include "scene/components/display/MeshRenderer.hpp"
 #include "display/mesh/CubeMesh.hpp"
+#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
 
 using namespace Dawn;
 
@@ -17,7 +18,7 @@ SceneItem * ExampleSpin::create(Scene *scene) {
   mr->mesh = new Mesh();
   mr->mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
   CubeMesh::buffer(mr->mesh, glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), 0, 0);
-  auto mat = item->addComponent<Material>();
+  auto mat = item->addComponent<SimpleTexturedMaterial>();
   item->addComponent<ExampleSpin>();
 
   return item;
diff --git a/src/dawnopengl/display/RenderManager.cpp b/src/dawnopengl/display/RenderManager.cpp
index acd3f5d8..8c7fa223 100644
--- a/src/dawnopengl/display/RenderManager.cpp
+++ b/src/dawnopengl/display/RenderManager.cpp
@@ -14,13 +14,12 @@ RenderManager::RenderManager(DawnGame *game) :
   backBuffer(*this),
   renderPipeline(this)
 {
-  this->simpleShader = new SimpleTexturedShader();
   this->uiShader = new UIShader();
 }
 
 void RenderManager::init() {
   this->renderPipeline.init();
-  this->simpleShader->compile();
+  this->simpleShader.compile();
   this->uiShader->compile();
 
   // Prepare the initial values
@@ -38,10 +37,6 @@ RenderPipeline * RenderManager::getRenderPipeline() {
   return &this->renderPipeline;
 }
 
-Shader * RenderManager::getDefaultShader() {
-  return this->simpleShader;
-}
-
 UIShader * RenderManager::getUIShader() {
   return this->uiShader;
 }
@@ -67,6 +62,5 @@ void RenderManager::update() {
 }
 
 RenderManager::~RenderManager() {
-  delete this->simpleShader;
   delete this->uiShader;
 }
\ No newline at end of file
diff --git a/src/dawnopengl/display/RenderManager.hpp b/src/dawnopengl/display/RenderManager.hpp
index ea3266c4..d903e493 100644
--- a/src/dawnopengl/display/RenderManager.hpp
+++ b/src/dawnopengl/display/RenderManager.hpp
@@ -16,7 +16,7 @@ namespace Dawn {
 
     public:
       BackBufferRenderTarget backBuffer;
-      SimpleTexturedShader *simpleShader;
+      SimpleTexturedShader simpleShader;
       UIShader *uiShader;
 
       /**
@@ -26,7 +26,6 @@ namespace Dawn {
       
       RenderTarget * getBackBuffer() override;
       RenderPipeline * getRenderPipeline() override;
-      Shader * getDefaultShader() override;
       UIShader * getUIShader() override;
       void setRenderFlags(renderflag_t renderFlags) override;
       void init() override;
diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.cpp b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp
new file mode 100644
index 00000000..f2fbb685
--- /dev/null
+++ b/src/dawnopengl/display/shader/SimpleTexturedShader.cpp
@@ -0,0 +1,43 @@
+// Copyright (c) 2023 Dominic Masters
+// 
+// This software is released under the MIT License.
+// https://opensource.org/licenses/MIT
+
+#include "SimpleTexturedShader.hpp"
+
+using namespace Dawn;
+
+void SimpleTexturedShader::compile() {
+  this->program.compile();
+}
+
+std::vector<struct ShaderPass> SimpleTexturedShader::getItemPasses(
+  MeshRenderer *mesh, Material *material
+) {
+  SimpleTexturedMaterial *simpleMaterial = dynamic_cast<SimpleTexturedMaterial*>(material);
+  assertNotNull(simpleMaterial);
+
+  struct ShaderPass onlyPass;
+  onlyPass.shaderProgram = &program;
+  onlyPass.colorValues[program.paramColor] = simpleMaterial->color;
+  onlyPass.matrixValues[program.paramModel] = mesh->transform->getWorldTransform();
+
+  if(simpleMaterial->texture != nullptr) {
+    onlyPass.boolValues[program.paramHasTexture] = true;
+    onlyPass.textureSlots[0] = simpleMaterial->texture;
+    onlyPass.textureValues[program.paramTexture] = 0;
+  } else {
+    onlyPass.boolValues[program.paramHasTexture] = false;
+  }
+
+  std::vector<struct ShaderPass> passes;
+  passes.push_back(onlyPass);
+  return passes;
+}
+
+void SimpleTexturedShader::setGlobalParameters(
+  glm::mat4 cameraProjection, glm::mat4 cameraView
+) {
+  this->program.setMatrix(this->program.paramProjection, cameraProjection);
+  this->program.setMatrix(this->program.paramView, cameraView);
+}
\ No newline at end of file
diff --git a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp
index f33bcbb6..900ee755 100644
--- a/src/dawnopengl/display/shader/SimpleTexturedShader.hpp
+++ b/src/dawnopengl/display/shader/SimpleTexturedShader.hpp
@@ -6,6 +6,7 @@
 #pragma once
 #include "display/shader/Shader.hpp"
 #include "SimpleTexturedShaderProgram.hpp"
+#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
 
 namespace Dawn {
   class SimpleTexturedShader : public Shader {
@@ -13,21 +14,14 @@ namespace Dawn {
       SimpleTexturedShaderProgram program;
 
     public:
-      void compile() override {
-        this->program.compile();
-      }
+      void compile() override;
 
       std::vector<struct ShaderPass> getItemPasses(
-        MeshRenderer *mesh,
-        Material *material
-      ) override {
-        return std::vector<struct ShaderPass>();
-      }
+        MeshRenderer *mesh, Material *material
+      ) override;
 
       void setGlobalParameters(
-        glm::mat4 cameraProjection,
-        glm::mat4 cameraView
-      ) override {
-      }
+        glm::mat4 cameraProjection, glm::mat4 cameraView
+      ) override;
   };
 }
\ No newline at end of file
diff --git a/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.cpp b/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.cpp
index 025695fa..e55b83b0 100644
--- a/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.cpp
+++ b/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.cpp
@@ -4,6 +4,7 @@
 // https://opensource.org/licenses/MIT
 
 #include "SimpleTexturedMaterial.hpp"
+#include "game/DawnGame.hpp"
 
 using namespace Dawn;
 
@@ -13,5 +14,5 @@ SimpleTexturedMaterial::SimpleTexturedMaterial(SceneItem *i) :
 }
 
 Shader * SimpleTexturedMaterial::getShader() {
-  return this->shader;
+  return &this->getGame()->renderManager.simpleShader;
 }
\ No newline at end of file
diff --git a/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.hpp b/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.hpp
index fb143006..cc6f2264 100644
--- a/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.hpp
+++ b/src/dawnopengl/scene/components/display/material/SimpleTexturedMaterial.hpp
@@ -4,13 +4,11 @@
 // https://opensource.org/licenses/MIT
 
 #pragma once
-#include "display/shader/SimpleTexturedShader.hpp"
 #include "scene/components/display/Material.hpp"
 
 namespace Dawn {
   class SimpleTexturedMaterial : public Material {
     public:
-      SimpleTexturedShader *shader = nullptr;
       Texture *texture = nullptr;
       struct Color color = COLOR_WHITE;
 
diff --git a/src/dawnpokergame/scenes/SubSceneRendererScene.hpp b/src/dawnpokergame/scenes/SubSceneRendererScene.hpp
index 8e366cc2..473d85b0 100644
--- a/src/dawnpokergame/scenes/SubSceneRendererScene.hpp
+++ b/src/dawnpokergame/scenes/SubSceneRendererScene.hpp
@@ -6,6 +6,7 @@
 #pragma once
 #include "scene/Scene.hpp"
 #include "game/DawnGame.hpp"
+#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
 
 namespace Dawn {
   template<class T>
@@ -35,9 +36,9 @@ namespace Dawn {
         this->sceneItem = this->createSceneItem();
         auto host = this->sceneItem->addComponent<MeshHost>();
         auto renderer = this->sceneItem->addComponent<MeshRenderer>();
-
-        auto material = this->sceneItem->addComponent<Material>();
-        material->textureValues[material->getShader()->getParameterByName("u_Text")] = this->subScene.renderTarget.getTexture();
+        
+        auto material = this->sceneItem->addComponent<SimpleTexturedMaterial>();
+        material->texture = this->subScene.renderTarget.getTexture();
 
         auto renderTargetQuad = this->sceneItem->addComponent<SimpleRenderTargetQuad>();
         renderTargetQuad->setRenderTarget(&this->subScene.renderTarget);