diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3e544910..e609d688 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -35,7 +35,6 @@ add_subdirectory(physics)
 add_subdirectory(poker)
 add_subdirectory(save)
 add_subdirectory(scene)
-add_subdirectory(ui)
 add_subdirectory(util)
 add_subdirectory(vn)
 
diff --git a/src/display/CMakeLists.txt b/src/display/CMakeLists.txt
index 530dc6da..b4c8a216 100644
--- a/src/display/CMakeLists.txt
+++ b/src/display/CMakeLists.txt
@@ -13,7 +13,7 @@ target_sources(${PROJECT_NAME}
     matrix.c
     render.c
     renderlist.c
-    shader.c
+    shaderprogram.c
     spritebatch.c
     texture.c
     tileset.c
@@ -21,4 +21,6 @@ target_sources(${PROJECT_NAME}
 
 # Subdirs
 add_subdirectory(animation)
-add_subdirectory(primitive)
\ No newline at end of file
+add_subdirectory(primitive)
+add_subdirectory(shaders)
+# add_subdirectory(ui)
\ No newline at end of file
diff --git a/src/display/renderlist.c b/src/display/renderlist.c
index 984dd765..114582ef 100644
--- a/src/display/renderlist.c
+++ b/src/display/renderlist.c
@@ -17,7 +17,7 @@ renderpass_t * renderListGetPass(renderlist_t *list, uint8_t pass) {
   return list->passes + pass;
 }
 
-uint8_t renderPassAdd(renderlist_t *list, shader_t *shader) {
+uint8_t renderPassAdd(renderlist_t *list, shaderprogram_t *shader) {
   uint8_t i;
   renderpass_t *pass;
 
@@ -46,7 +46,7 @@ renderpass_t * renderListRenderPass(
   return renderPass;
 }
 
-void renderListRender(renderlist_t *list, shader_t *shader) {
+void renderListRender(renderlist_t *list, renderlistbackshader_t *backShader) {
   camera_t camera;
   int32_t i;
   renderpass_t *pass;
@@ -59,38 +59,21 @@ void renderListRender(renderlist_t *list, shader_t *shader) {
   frameBufferUse(&list->frame, true);
 
   // Set the shader
-  shaderUse(shader);
-  shaderUseCamera(shader, &camera);
-  shaderUsePosition(shader, 0,0,0, 0,0,0);
+  shaderUse(backShader->program);
+  shaderUseCamera(
+    backShader->program, backShader->uniformView,
+    backShader->uniformProjection, &camera
+  );
+  shaderUsePosition(backShader->program, backShader->uniformPosition,
+    0,0,0, 0,0,0
+  );
 
   // Render each pass.
   for(i = 0; i < list->passCount; i++) {
     pass = renderListGetPass(list, i);
-    shaderUseTexture(shader, &pass->frame.texture);
-    primitiveDraw(&list->quad, 0, -1);
+    textureBind(&pass->frame.texture, i);
+    shaderUseTexture(backShader->program, backShader->uniformTexture[i], i);
   }
-}
-
-void renderListAsBackbuffer(
-  renderlist_t *list, engine_t *engine, shader_t *shader,
-  shaderuniform_t *uniforms
-) {
-  camera_t camera;
-
-  // Reset to backbuffer
-  renderResetFramebuffer(&engine->render);
-
-  // Setup camera to look right at teh quad.
-  cameraLookAt(&camera, 0,0,1, 0,0,0);
-  cameraOrtho(&camera, 0,1, 0,1, 0.5f, 1.5f);
-
-  // Set up the shader.
-  shaderUse(shader); 
-  shaderUseCamera(shader, &camera);
-  shaderUsePosition(shader, 0,0,0, 0,0,0);
-  shaderUseTexture(shader, &list->frame.texture);
-
-  // Render the quad to the back buffer.
   primitiveDraw(&list->quad, 0, -1);
 }
 
diff --git a/src/display/renderlist.h b/src/display/renderlist.h
index 8df72778..fa9b1683 100644
--- a/src/display/renderlist.h
+++ b/src/display/renderlist.h
@@ -9,7 +9,7 @@
 #include "../libs.h"
 #include "framebuffer.h"
 #include "primitive/primitive.h"
-#include "shader.h"
+#include "shaderprogram.h"
 #include "camera.h"
 #include "../engine/engine.h"
 #include "primitive/quad.h"
@@ -20,7 +20,7 @@
 
 typedef struct {
   framebuffer_t frame;
-  shader_t *shader;
+  shaderprogram_t *shader;
 } renderpass_t;
 
 typedef struct {
@@ -32,11 +32,12 @@ typedef struct {
 } renderlist_t;
 
 typedef struct {
-  shader_t shader;
-  shaderuniform_t uniformTexture;
+  shaderprogram_t *program;
   shaderuniform_t uniformView;
+  shaderuniform_t uniformPosition;
   shaderuniform_t uniformProjection;
-} renderlistbackbuffershader_t;
+  shaderuniform_t uniformTexture[RENDER_PASSES_MAX];
+} renderlistbackshader_t;
 
 /**
  * Initialize a render pass list.
@@ -63,7 +64,7 @@ renderpass_t * renderListGetPass(renderlist_t *list, uint8_t pass);
  * @param shader Shader to use for the render pass.
  * @return The render pass index.
  */
-uint8_t renderPassAdd(renderlist_t *list, shader_t *shader);
+uint8_t renderPassAdd(renderlist_t *list, shaderprogram_t *shader);
 
 /**
  * Prepare the rendering for a specific render pass. This will set up the 
@@ -85,24 +86,9 @@ renderpass_t * renderListRenderPass(
  * texture indexes.
  * 
  * @param list List to render.
- * @param shader Shader to use while rendering.
+ * @param backShader Shader to use while rendering.
  */
-void renderListRender(renderlist_t *list, shader_t *shader);
-
-/**
- * Takes a previously rendered render list and renders it to the backbuffer. 
- * You could do this manually, but this method makes the assumption that the
- * render list is the only thing to be rendered to the backbuffer (currently).
- * 
- * @param list Render list to render to the backbuffer
- * @param engine Engine to use when rendering.
- * @param shader Shader to use to render to the backbuffer.
- * @param uniforms Uniforms for the back buffer. [ view, proj, model, text ]
- */
-void renderListAsBackbuffer(
-  renderlist_t *list, engine_t *engine, shader_t *shader,
-  shaderuniform_t *uniforms
-);
+void renderListRender(renderlist_t *list, renderlistbackshader_t *backShader);
 
 /**
  * Resize an existing render list and all its render pass frame buffers. This
diff --git a/src/display/shader.c b/src/display/shaderprogram.c
similarity index 66%
rename from src/display/shader.c
rename to src/display/shaderprogram.c
index 24b65779..a04bd07c 100644
--- a/src/display/shader.c
+++ b/src/display/shaderprogram.c
@@ -5,21 +5,18 @@
  * https://opensource.org/licenses/MIT
  */
 
-#include "shader.h"
+#include "shaderprogram.h"
 
-void shaderInit(shader_t *shader,
+void shaderInit(shaderprogram_t *shader,
   char *vertexShaderSource, char* fragmentShaderSource
 ) {
   int isSuccess, maxLength;
   char *error;
   GLuint shaderVertex, shaderFragment, shaderProgram;
 
-  GLchar const* filesVertex[] = { vertexShaderSource };
-  GLchar const* filesFragment[] = { fragmentShaderSource };
-
   // Load the vertex shader first
   shaderVertex = glCreateShader(GL_VERTEX_SHADER);
-  glShaderSource(shaderVertex, 1, filesVertex, 0);
+  glShaderSource(shaderVertex, 1, &vertexShaderSource, 0);
   glCompileShader(shaderVertex);
 
   // Validate
@@ -35,7 +32,7 @@ void shaderInit(shader_t *shader,
 
   // Now load the Frag shader
   shaderFragment = glCreateShader(GL_FRAGMENT_SHADER);
-  glShaderSource(shaderFragment, 1, filesFragment, 0);
+  glShaderSource(shaderFragment, 1, &fragmentShaderSource, 0);
   glCompileShader(shaderFragment);
   glGetShaderiv(shaderFragment, GL_COMPILE_STATUS, &isSuccess);
   if(!isSuccess) {
@@ -71,48 +68,42 @@ void shaderInit(shader_t *shader,
   shader->shaderVertex = shaderVertex;
   shader->shaderFrag = shaderFragment;
   shader->shaderProgram = shaderProgram;
-
-  shader->uniProj = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_PROJ);
-  shader->uniView = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_VIEW);
-  shader->uniText = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_TEXT);
-  shader->uniModl = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_MODL);
-  shader->uniColr = glGetUniformLocation(shader->shaderProgram,SHADER_UNI_COLR);
-
+  
   // Bind the shader
   shaderUse(shader);
-
-  // Reset position
-  shaderUsePosition(shader, 0, 0, 0, 0, 0, 0);
-  shaderUseColor(shader, PIXEL_COLOR_WHITE);
 }
 
-void shaderDispose(shader_t *shader) {
+void shaderDispose(shaderprogram_t *shader) {
   glDeleteProgram(shader->shaderProgram);
   glDeleteShader(shader->shaderVertex);
   glDeleteShader(shader->shaderFrag);
 }
 
-void shaderUse(shader_t *shader) {
+void shaderUse(shaderprogram_t *shader) {
   glUseProgram(shader->shaderProgram);
 }
 
-void shaderUseCamera(shader_t *shader, camera_t *camera) {
-  shaderUseMatrix(shader, shader->uniView, &camera->view);
-  shaderUseMatrix(shader, shader->uniProj, &camera->projection);
+void shaderUseCamera(
+  shaderprogram_t *shader, shaderuniform_t uniformView,
+  shaderuniform_t uniformProjection, camera_t *camera
+) {
+  shaderUseMatrix(shader, uniformView, &camera->view);
+  shaderUseMatrix(shader, uniformProjection, &camera->projection);
 }
 
-void shaderUseTexture(shader_t *shader, texture_t *texture) {
-  // OpenGL requires us to set the active texure.
-  glActiveTexture(GL_TEXTURE0);
-  glBindTexture(GL_TEXTURE_2D, texture->id);
-  glUniform1i(shader->uniText, 0);
+void shaderUseTexture(
+  shaderprogram_t *shader, shaderuniform_t uniform, textureslot_t slot
+) {
+  glUniform1i(uniform, slot);
 }
 
-void shaderUseMatrix(shader_t *shader,shaderuniform_t uniform,matrix_t *matrix){
+void shaderUseMatrix(
+  shaderprogram_t *shader, shaderuniform_t uniform, matrix_t *matrix
+) {
   glUniformMatrix4fv(uniform, 1, GL_FALSE, matrix->internalMatrix[0]);
 }
 
-void shaderUsePosition(shader_t *shader,
+void shaderUsePosition(shaderprogram_t *shader, shaderuniform_t uniform,
   float x, float y, float z,
   float pitch, float yaw, float roll
 ) {
@@ -125,10 +116,10 @@ void shaderUsePosition(shader_t *shader,
   matrixRotate(&matrix, yaw, 0, 1, 0);
   matrixRotate(&matrix, roll, 0, 0, 1);
   matrixRotate(&matrix, pitch, 1, 0, 0);
-  shaderUseMatrix(shader, shader->uniModl, &matrix);
+  shaderUseMatrix(shader, uniform, &matrix);
 }
 
-void shaderUsePositionAndScale(shader_t *shader,
+void shaderUsePositionAndScale(shaderprogram_t *shader, shaderuniform_t uniform,
   float x, float y, float z,
   float pitch, float yaw, float roll,
   float scaleX, float scaleY, float scaleZ
@@ -145,14 +136,20 @@ void shaderUsePositionAndScale(shader_t *shader,
 
   matrixScale(&matrix, scaleX, scaleY, scaleZ);
 
-  shaderUseMatrix(shader, shader->uniModl, &matrix);
+  shaderUseMatrix(shader, uniform, &matrix);
 }
 
-void shaderUseColor(shader_t *shader, pixel_t color) {
-  glUniform4f(shader->uniColr,
+void shaderUseColor(
+  shaderprogram_t *shader, shaderuniform_t uniform, pixel_t color
+) {
+  glUniform4f(uniform,
     (float)color.r / 255.0f,
     (float)color.g / 255.0f,
     (float)color.b / 255.0f,
     (float)color.a / 255.0f 
   );
+}
+
+shaderuniform_t shaderGetUniformByName(shaderprogram_t *sp, const char *name) {
+  return glGetUniformLocation(sp->shaderProgram, name);
 }
\ No newline at end of file
diff --git a/src/display/shader.h b/src/display/shaderprogram.h
similarity index 65%
rename from src/display/shader.h
rename to src/display/shaderprogram.h
index db2ad9c1..598fff9e 100644
--- a/src/display/shader.h
+++ b/src/display/shaderprogram.h
@@ -11,12 +11,6 @@
 #include "camera.h"
 #include "texture.h"
 
-#define SHADER_UNI_VIEW "u_View"
-#define SHADER_UNI_PROJ "u_Proj"
-#define SHADER_UNI_TEXT "u_Text"
-#define SHADER_UNI_MODL "u_Model"
-#define SHADER_UNI_COLR "u_Colr"
-
 /** Representation of a shader uniform */
 typedef GLuint shaderuniform_t;
 
@@ -33,59 +27,56 @@ typedef struct {
 
   /** Pointer to an uploaded shader program linked */
   shaderuniform_t shaderProgram;
-
-  /** Matrix for the view matrix */
-  shaderuniform_t uniView;
-
-  /** Matrix for the projection matrix */
-  shaderuniform_t uniProj;
-
-  /** Uniform for the current texture */
-  shaderuniform_t uniText;
-
-  /** Uniform for the current model world position */
-  shaderuniform_t uniModl;
-
-  /** Uniform for the color multiplier */
-  shaderuniform_t uniColr;
-} shader_t;
+} shaderprogram_t;
 
 /**
  * Compiles a shader from vertex and fragment shader code.
+ * 
  * @param shader Shader to compile into.
  * @param vertexShaderSource The raw vertex shader code.
  * @param fragmentShaderSource The raw fragment shader code.
  */
-void shaderInit(shader_t *shader,
+void shaderInit(shaderprogram_t *shader,
   char *vertexShaderSource, char* fragmentShaderSource
 );
 
 /**
  * Cleanup and unload a previously loaded shader.
+ * 
  * @param shader The shader to unload
  */
-void shaderDispose(shader_t *shader);
+void shaderDispose(shaderprogram_t *shader);
 
 /**
  * Attaches the supplied shader as the current shader.
+ * 
  * @param shader The shader to attach
  */
-void shaderUse(shader_t *shader);
-
+void shaderUse(shaderprogram_t *shader);
 
 /**
  * Attaches a camera to the shader.
+ * 
  * @param shader Shader to attach to.
+ * @param uniformView Uniform for the view matrix
+ * @param uniformProjection Uniform for the projection matrix.
  * @param camera Camera to attach.
  */
-void shaderUseCamera(shader_t *shader, camera_t *camera);
+void shaderUseCamera(
+  shaderprogram_t *shader, shaderuniform_t uniformView,
+  shaderuniform_t uniformProjection, camera_t *camera
+);
 
 /**
  * Attaches a texture to the shader.
+ * 
  * @param shader Shader to attach to.
- * @param texture Texture to attach.
+ * @param uniform Uniform to set the texture on to.
+ * @param slot Which texture slot to bind to the uniform.
  */
-void shaderUseTexture(shader_t *shader, texture_t *texture);
+void shaderUseTexture(
+  shaderprogram_t *shader, shaderuniform_t uniform, textureslot_t slot
+);
 
 /**
  * Set's a specific shader uniform to a matrix.
@@ -94,12 +85,15 @@ void shaderUseTexture(shader_t *shader, texture_t *texture);
  * @param uniform Uniform on the shader to set.
  * @param matrix Matrix to apply.
  */
-void shaderUseMatrix(shader_t *shader,shaderuniform_t uniform,matrix_t *matrix);
+void shaderUseMatrix(
+  shaderprogram_t *shader, shaderuniform_t uniform, matrix_t *matrix
+);
 
 /**
  * Set's the current translation matrix onto the shader for the next
  * render to use. Rotation order is set to YZX.
  * @param shader Shader to attach to.
+ * @param uniform Uniform to set the position on to.
  * @param x X coordinate (world space).
  * @param y Y coordinate (world space).
  * @param z Z coordinate (world space).
@@ -107,7 +101,7 @@ void shaderUseMatrix(shader_t *shader,shaderuniform_t uniform,matrix_t *matrix);
  * @param yaw Yaw of the object (local space).
  * @param roll Roll of the object (local space).
  */
-void shaderUsePosition(shader_t *shader,
+void shaderUsePosition(shaderprogram_t *shader, shaderuniform_t uniform,
   float x, float y, float z,
   float pitch, float yaw, float roll
 );
@@ -118,6 +112,7 @@ void shaderUsePosition(shader_t *shader,
  * render to use. Also provides scaling controls.
  * 
  * @param shader Shader to attach to.
+ * @param uniform Uniform to set the position on to.
  * @param x X coordinate (world space).
  * @param y Y coordinate (world space).
  * @param z Z coordinate (world space).
@@ -128,11 +123,28 @@ void shaderUsePosition(shader_t *shader,
  * @param scaleY Y scale of model (1 being 100% scaled).
  * @param scaleZ Z scale of model (1 being 100% scaled).
  */
-void shaderUsePositionAndScale(shader_t *shader,
+void shaderUsePositionAndScale(shaderprogram_t *shader, shaderuniform_t uniform,
   float x, float y, float z,
   float pitch, float yaw, float roll,
   float scaleX, float scaleY, float scaleZ
 );
 
+/**
+ * Set a color on to the shader.
+ * 
+ * @param shader Shader to set the color on to.
+ * @param uniform Uniform to set the color to.
+ * @param color Color to set.
+ */
+void shaderUseColor(
+  shaderprogram_t *shader, shaderuniform_t uniform, pixel_t color
+);
 
-void shaderUseColor(shader_t *shader, pixel_t color);
\ No newline at end of file
+/**
+ * Locate a shader uniform by its name.
+ * 
+ * @param sp Shader program to get the uniform for.
+ * @param name Name of the uniform to get.
+ * @return The shader uniform.
+ */
+shaderuniform_t shaderGetUniformByName(shaderprogram_t *sp, const char *name);
\ No newline at end of file
diff --git a/src/display/shaders/CMakeLists.txt b/src/display/shaders/CMakeLists.txt
new file mode 100644
index 00000000..65135a19
--- /dev/null
+++ b/src/display/shaders/CMakeLists.txt
@@ -0,0 +1,11 @@
+# Copyright (c) 2021 Dominic Msters
+# 
+# This software is released under the MIT License.
+# https://opensource.org/licenses/MIT
+
+# Sources
+# target_sources(${PROJECT_NAME}
+#   PRIVATE
+#     standardshader.c
+#     shaderui.c
+# )
\ No newline at end of file
diff --git a/src/display/shaders/shaderui.c b/src/display/shaders/shaderui.c
new file mode 100644
index 00000000..eaf4c3e1
--- /dev/null
+++ b/src/display/shaders/shaderui.c
@@ -0,0 +1,12 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include "shaderui.h"
+
+void shaderUiInit(shaderprogram_t *program) {
+  
+}
\ No newline at end of file
diff --git a/src/display/shaders/shaderui.h b/src/display/shaders/shaderui.h
new file mode 100644
index 00000000..674c21ff
--- /dev/null
+++ b/src/display/shaders/shaderui.h
@@ -0,0 +1,22 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+#include "../shaderprogram.h"
+#include "../texture.h"
+
+typedef struct {
+  shaderprogram_t program;
+  texture_t texture;
+
+  shaderuniform_t uniProjection;
+  shaderuniform_t uniModel;
+  shaderuniform_t uniTexture;
+  shaderuniform_t uniColor;
+} uishader_t;
+
+void shaderUiInit(shaderprogram_t *program);
\ No newline at end of file
diff --git a/src/display/shaders/standardshader.c b/src/display/shaders/standardshader.c
new file mode 100644
index 00000000..11045933
--- /dev/null
+++ b/src/display/shaders/standardshader.c
@@ -0,0 +1,11 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#include "standardshader.h"
+
+void standardShaderInit(standardshader_t *stds, char *vert, char *frag) {
+}
\ No newline at end of file
diff --git a/src/display/shaders/standardshader.h b/src/display/shaders/standardshader.h
new file mode 100644
index 00000000..320f492d
--- /dev/null
+++ b/src/display/shaders/standardshader.h
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2021 Dominic Masters
+ * 
+ * This software is released under the MIT License.
+ * https://opensource.org/licenses/MIT
+ */
+
+#pragma once
+#include "../../libs.h"
+#include "../shaderprogram.h"
+
+#define STANDARD_SHADER_UNIFORM_NAME_VIEW "u_View"
+#define STANDARD_SHADER_UNIFORM_NAME_PROJ "u_Proj"
+#define STANDARD_SHADER_UNIFORM_NAME_TEXT "u_Text"
+#define STANDARD_SHADER_UNIFORM_NAME_MODEL "u_Model"
+#define STANDARD_SHADER_UNIFORM_NAME_COLOR "u_Color"
+
+typedef struct {
+  shaderprogram_t shader;
+
+  shaderuniform_t uniformView;
+  shaderuniform_t uniformProjection;
+  shaderuniform_t uniformPosition;
+  shaderuniform_t uniformTexture;
+  shaderuniform_t uniformColor;
+} standardshader_t;
+
+void standardShaderInit(standardshader_t *stds, char *vert, char *frag);
\ No newline at end of file
diff --git a/src/display/texture.c b/src/display/texture.c
index 265b8350..05340c73 100644
--- a/src/display/texture.c
+++ b/src/display/texture.c
@@ -45,8 +45,13 @@ void textureInit(texture_t *texture, int32_t width, int32_t height,
       GL_RGBA, GL_UNSIGNED_BYTE, pixels
     );
   }
-  
-  glBindTexture(GL_TEXTURE_2D, 0);
+
+  textureBind(texture, 0x00);
+}
+
+void textureBind(texture_t *texture, textureslot_t slot) {
+  glActiveTexture(GL_TEXTURE0 + slot);
+  glBindTexture(GL_TEXTURE_2D, texture->id);
 }
 
 void textureBufferPixels(texture_t *texture,
diff --git a/src/display/texture.h b/src/display/texture.h
index 8f1745e1..7c278dc4 100644
--- a/src/display/texture.h
+++ b/src/display/texture.h
@@ -6,6 +6,11 @@
 #pragma once
 #include "../libs.h"
 
+#define TEXTURE_SLOTS_MAX 8
+
+/** Texture slot that a texture can be bound to */
+typedef GLuint textureslot_t;
+
 /**
  * Structure detailing information about a texture.
  * Because we plan to upload the pixels of a texture into the GPU, we don't
@@ -45,6 +50,14 @@ void textureInit(texture_t *texture, int32_t width, int32_t height,
   pixel_t *pixels
 );
 
+/**
+ * Bind a texture on to a given texture slot.
+ * 
+ * @param texture Texture to bind.
+ * @param slot Slot to bind the texture to.
+ */
+void textureBind(texture_t *texture, textureslot_t slot);
+
 /**
  * Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
  * doing this too often.
diff --git a/src/ui/CMakeLists.txt b/src/display/ui/CMakeLists.txt
similarity index 100%
rename from src/ui/CMakeLists.txt
rename to src/display/ui/CMakeLists.txt
diff --git a/src/ui/align.c b/src/display/ui/align.c
similarity index 100%
rename from src/ui/align.c
rename to src/display/ui/align.c
diff --git a/src/ui/align.h b/src/display/ui/align.h
similarity index 96%
rename from src/ui/align.h
rename to src/display/ui/align.h
index e9a20043..9b2df946 100644
--- a/src/ui/align.h
+++ b/src/display/ui/align.h
@@ -6,8 +6,8 @@
  */
 
 #pragma once
-#include "../libs.h"
-#include "../util/flags.h"
+#include "../../libs.h"
+#include "../../util/flags.h"
 
 #define ALIGN_POS_CENTER flagDefine(0)
 #define ALIGN_POS_START flagDefine(1)
diff --git a/src/ui/breakpoint.c b/src/display/ui/breakpoint.c
similarity index 100%
rename from src/ui/breakpoint.c
rename to src/display/ui/breakpoint.c
diff --git a/src/ui/breakpoint.h b/src/display/ui/breakpoint.h
similarity index 98%
rename from src/ui/breakpoint.h
rename to src/display/ui/breakpoint.h
index b9cfd3c0..6fdb0056 100644
--- a/src/ui/breakpoint.h
+++ b/src/display/ui/breakpoint.h
@@ -4,7 +4,7 @@
 // https://opensource.org/licenses/MIT
 
 #pragma once
-#include "../libs.h"
+#include "../../libs.h"
 
 /** Maximum breakpoints that the list can support. */
 #define BREAKPOINT_COUNT_MAX 0x04
diff --git a/src/ui/frame.c b/src/display/ui/frame.c
similarity index 97%
rename from src/ui/frame.c
rename to src/display/ui/frame.c
index c5cacd28..c76a4b32 100644
--- a/src/ui/frame.c
+++ b/src/display/ui/frame.c
@@ -100,7 +100,7 @@ void frameSetInnerSize(frame_t *frame, float width, float height) {
   );
 }
 
-void frameRender(frame_t *frame, shader_t *shader, float x, float y) {
+void frameRender(frame_t *frame, shaderprogram_t *shader, float x, float y) {
   if(frame->texture == NULL) return;
   shaderUsePosition(shader, x, y, 0,  0, 0, 0);
   shaderUseTexture(shader, frame->texture);
diff --git a/src/ui/frame.h b/src/display/ui/frame.h
similarity index 85%
rename from src/ui/frame.h
rename to src/display/ui/frame.h
index 82676938..2db45baf 100644
--- a/src/ui/frame.h
+++ b/src/display/ui/frame.h
@@ -6,11 +6,11 @@
  */
 
 #pragma once
-#include "../libs.h"
-#include "../display/shader.h"
-#include "../display/primitive/primitive.h"
-#include "../display/primitive/quad.h"
-#include "../display/font.h"
+#include "../../libs.h"
+#include "../shaderprogram.h"
+#include "../primitive/primitive.h"
+#include "../primitive/quad.h"
+#include "../font.h"
 
 /** Size of the border (in pixels) on each edge */
 #define FRAME_BORDER_SIZE 16
@@ -57,7 +57,7 @@ void frameSetInnerSize(frame_t *frame, float width, float height);
  * @param x X position.
  * @param y Y position.
  */
-void frameRender(frame_t *frame, shader_t *shader, float x, float y);
+void frameRender(frame_t *frame, shaderprogram_t *shader, float x, float y);
 
 /**
  * Cleanup a previously initialized frame.
diff --git a/src/ui/framedtextmenu.c b/src/display/ui/framedtextmenu.c
similarity index 94%
rename from src/ui/framedtextmenu.c
rename to src/display/ui/framedtextmenu.c
index e21810be..e88bf5eb 100644
--- a/src/ui/framedtextmenu.c
+++ b/src/display/ui/framedtextmenu.c
@@ -30,7 +30,7 @@ void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine) {
 }
 
 void framedTextMenuRender(
-  framedtextmenu_t *menu, shader_t *shader, float x, float y
+  framedtextmenu_t *menu, shaderprogram_t *shader, float x, float y
 ) {
   frameRender(&menu->frame, shader, x, y);
   textMenuRender(&menu->menu, shader, x, y);
diff --git a/src/ui/framedtextmenu.h b/src/display/ui/framedtextmenu.h
similarity index 95%
rename from src/ui/framedtextmenu.h
rename to src/display/ui/framedtextmenu.h
index 0e62b8a9..f4ec2d37 100644
--- a/src/ui/framedtextmenu.h
+++ b/src/display/ui/framedtextmenu.h
@@ -56,7 +56,7 @@ void framedTextMenuUpdate(framedtextmenu_t *menu, engine_t *engine);
  * @param y Y Position.
  */
 void framedTextMenuRender(
-  framedtextmenu_t *menu, shader_t *shader, float x, float y
+  framedtextmenu_t *menu, shaderprogram_t *shader, float x, float y
 );
 
 /**
diff --git a/src/ui/grid.c b/src/display/ui/grid.c
similarity index 100%
rename from src/ui/grid.c
rename to src/display/ui/grid.c
diff --git a/src/ui/grid.h b/src/display/ui/grid.h
similarity index 100%
rename from src/ui/grid.h
rename to src/display/ui/grid.h
diff --git a/src/ui/image.c b/src/display/ui/image.c
similarity index 94%
rename from src/ui/image.c
rename to src/display/ui/image.c
index 014284ce..df5fec45 100644
--- a/src/ui/image.c
+++ b/src/display/ui/image.c
@@ -46,7 +46,7 @@ void imageSetTextureAndCrop(image_t *image, texture_t *texture,
   );
 }
 
-void imageRender(image_t *image, shader_t *shader, float x, float y) {
+void imageRender(image_t *image, shaderprogram_t *shader, float x, float y) {
   if(image->texture == NULL) return;
   shaderUsePositionAndScale(shader,
     x,y,0,
diff --git a/src/ui/image.h b/src/display/ui/image.h
similarity index 92%
rename from src/ui/image.h
rename to src/display/ui/image.h
index 4051b8ff..1f59bd0b 100644
--- a/src/ui/image.h
+++ b/src/display/ui/image.h
@@ -10,7 +10,7 @@
 #include "../display/primitive/primitive.h"
 #include "../display/primitive/quad.h"
 #include "../display/texture.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 
 typedef struct {
   texture_t *texture;
@@ -56,7 +56,7 @@ void imageSetTextureAndCrop(image_t *image, texture_t *texture,
  * @param x X position.
  * @param y Y position.
  */
-void imageRender(image_t *image, shader_t *shader, float x, float y);
+void imageRender(image_t *image, shaderprogram_t *shader, float x, float y);
 
 /**
  * Cleanup a previously initialized image.
diff --git a/src/ui/label.c b/src/display/ui/label.c
similarity index 92%
rename from src/ui/label.c
rename to src/display/ui/label.c
index 06827a76..810876a7 100644
--- a/src/ui/label.c
+++ b/src/display/ui/label.c
@@ -27,7 +27,7 @@ void labelSetText(label_t *label, font_t *font, char *text) {
   );
 }
 
-void labelRender(label_t *label, shader_t *shader, float x, float y) {
+void labelRender(label_t *label, shaderprogram_t *shader, float x, float y) {
   if(label->primitive.verticeCount == 0) return;
   shaderUsePosition(shader, x,y,0, 0,0,0);
   shaderUseTexture(shader, &label->font->texture);
diff --git a/src/ui/label.h b/src/display/ui/label.h
similarity index 89%
rename from src/ui/label.h
rename to src/display/ui/label.h
index 4c50bdaa..94cb5ade 100644
--- a/src/ui/label.h
+++ b/src/display/ui/label.h
@@ -5,7 +5,7 @@
 
 #pragma once
 #include "../libs.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 #include "../display/primitive/primitive.h"
 #include "../display/font.h"
 
@@ -41,7 +41,7 @@ void labelSetText(label_t *label, font_t *font, char *text);
  * @param x X position.
  * @param y Y position.
  */
-void labelRender(label_t *label, shader_t *shader, float x, float y);
+void labelRender(label_t *label, shaderprogram_t *shader, float x, float y);
 
 /**
  * Dispose a previously created label.
diff --git a/src/ui/menu.c b/src/display/ui/menu.c
similarity index 100%
rename from src/ui/menu.c
rename to src/display/ui/menu.c
diff --git a/src/ui/menu.h b/src/display/ui/menu.h
similarity index 100%
rename from src/ui/menu.h
rename to src/display/ui/menu.h
diff --git a/src/ui/rectangle.c b/src/display/ui/rectangle.c
similarity index 90%
rename from src/ui/rectangle.c
rename to src/display/ui/rectangle.c
index fff11d1d..8dde9b80 100644
--- a/src/ui/rectangle.c
+++ b/src/display/ui/rectangle.c
@@ -20,7 +20,9 @@ void rectangleSetColor(rectangle_t *rectangle, pixel_t color) {
   );
 }
 
-void rectangleRender(rectangle_t *rect, shader_t *shader, float x, float y) {
+void rectangleRender(
+  rectangle_t *rect, shaderprogram_t *shader, float x, float y
+) {
   shaderUsePositionAndScale(shader,
     x, y, 0,
     0, 0, 0,
diff --git a/src/ui/rectangle.h b/src/display/ui/rectangle.h
similarity index 87%
rename from src/ui/rectangle.h
rename to src/display/ui/rectangle.h
index 518aaa09..f3599014 100644
--- a/src/ui/rectangle.h
+++ b/src/display/ui/rectangle.h
@@ -8,7 +8,7 @@
 #pragma once
 #include "../libs.h"
 #include "../display/texture.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 #include "../display/primitive/primitive.h"
 #include "../display/primitive/quad.h"
 
@@ -23,7 +23,7 @@ void rectangleInit(rectangle_t *rectangle);
 void rectangleSetColor(rectangle_t *rectangle, pixel_t color);
 
 void rectangleRender(
-  rectangle_t *rect, shader_t *shader,
+  rectangle_t *rect, shaderprogram_t *shader,
   float x, float y
 );
 
diff --git a/src/ui/textmenu.c b/src/display/ui/textmenu.c
similarity index 95%
rename from src/ui/textmenu.c
rename to src/display/ui/textmenu.c
index 8afc1763..86d56ca7 100644
--- a/src/ui/textmenu.c
+++ b/src/display/ui/textmenu.c
@@ -35,7 +35,9 @@ menuitem_t * textMenuAdd(textmenu_t *menu, char *item) {
   return menuAdd(&menu->menu);
 }
 
-void textMenuRender(textmenu_t *menu, shader_t *shader, float x, float y) {
+void textMenuRender(
+  textmenu_t *menu, shaderprogram_t *shader, float x, float y
+) {
   uint8_t i;
   label_t *label;
   menuitem_t *item;
diff --git a/src/ui/textmenu.h b/src/display/ui/textmenu.h
similarity index 95%
rename from src/ui/textmenu.h
rename to src/display/ui/textmenu.h
index b9d2208a..ae85af3f 100644
--- a/src/ui/textmenu.h
+++ b/src/display/ui/textmenu.h
@@ -59,7 +59,7 @@ menuitem_t * textMenuAdd(textmenu_t *menu, char *item);
  * @param x X position of the menu.
  * @param y Y position of the menu.
  */
-void textMenuRender(textmenu_t *menu, shader_t *shader, float x, float y);
+void textMenuRender(textmenu_t *menu, shaderprogram_t *shader,float x, float y);
 
 /**
  * Dispose/Cleanup a text menu.
diff --git a/src/file/asset.h b/src/file/asset.h
index 4303b0b4..270b781e 100644
--- a/src/file/asset.h
+++ b/src/file/asset.h
@@ -7,8 +7,6 @@
 
 #pragma once
 #include "../libs.h"
-#include "../display/shader.h"
-#include "../display/texture.h"
 #include "../display/font.h"
 
 #if !defined(ASSET_PREFIX)
diff --git a/src/file/types/shader.h b/src/file/types/shader.h
index be9d2a5c..af7f5de5 100644
--- a/src/file/types/shader.h
+++ b/src/file/types/shader.h
@@ -5,10 +5,10 @@
 
 #pragma once
 #include "../../libs.h"
-#include "../../display/shader.h"
+#include "../../display/shaderprogram.h"
 
 typedef struct {
-  shader_t shader;
+  shaderprogram_t shader;
   char *fileVert;
   char *fileFrag;
   char *dataVert;
diff --git a/src/games/poker/game.h b/src/games/poker/game.h
index 99b63474..e1f10b78 100644
--- a/src/games/poker/game.h
+++ b/src/games/poker/game.h
@@ -11,12 +11,12 @@
 #include "../../display/primitive/primitive.h"
 #include "../../display/primitive/quad.h"
 #include "../../display/primitive/cube.h"
-#include "../../display/shader.h"
+#include "../../display/shaderprogram.h"
 
 typedef struct {
   engine_t engine;
   camera_t camera;
-  shader_t shader;
+  shaderprogram_t shader;
   primitive_t quad;
   assetmanagerowner_t owner;
   assetmanageritem_t *item;
diff --git a/src/scene/scene.h b/src/scene/scene.h
index c0cddbd4..0d12b591 100644
--- a/src/scene/scene.h
+++ b/src/scene/scene.h
@@ -10,7 +10,7 @@
 #include "../file/assetmanager.h"
 #include "../engine/engine.h"
 #include "../display/renderlist.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 
 // Forwarder for scene_t
 typedef struct _scene_t scene_t;
diff --git a/src/vn/conversation/vnconversation.c b/src/vn/conversation/vnconversation.c
index 0a0f8d21..e0d1cb0b 100644
--- a/src/vn/conversation/vnconversation.c
+++ b/src/vn/conversation/vnconversation.c
@@ -33,7 +33,7 @@ void vnConversationUpdate(vnconversation_t *convo, engine_t *engine) {
 }
 
 void vnConversationRender(
-  vnconversation_t *convo, engine_t *engine, shader_t *shader
+  vnconversation_t *convo, engine_t *engine, shaderprogram_t *shader
 ) {
   vnTextBoxRender(
     &convo->textbox, shader,
diff --git a/src/vn/conversation/vnconversation.h b/src/vn/conversation/vnconversation.h
index ef89950e..95164cc8 100644
--- a/src/vn/conversation/vnconversation.h
+++ b/src/vn/conversation/vnconversation.h
@@ -11,6 +11,7 @@
 #include "../../util/array.h"
 #include "../../display/animation/timeline.h"
 #include "../../display/animation/queue.h"
+#include "../../display/shaderprogram.h"
 #include "../vncharacter.h"
 #include "../../engine/engine.h"
 
@@ -69,7 +70,7 @@ void vnConversationUpdate(vnconversation_t *convo, engine_t *engine);
  * @param shader Shader to use while rendering.
  */
 void vnConversationRender(
-  vnconversation_t *convo, engine_t *engine, shader_t *shader
+  vnconversation_t *convo, engine_t *engine, shaderprogram_t *shader
 );
 
 /**
diff --git a/src/vn/ui/vntextbox.c b/src/vn/ui/vntextbox.c
index 042cd7e7..4a48e403 100644
--- a/src/vn/ui/vntextbox.c
+++ b/src/vn/ui/vntextbox.c
@@ -77,7 +77,9 @@ void vnTextBoxUpdate(vntextbox_t *box, engine_t *engine) {
   box->lineCurrent += box->linesMax;
 }
 
-void vnTextBoxRender(vntextbox_t *box, shader_t *shader, float x, float y) {
+void vnTextBoxRender(
+  vntextbox_t *box, shaderprogram_t *shader, float x, float y
+) {
   int32_t charStart, charCount;
   float yOffset;
   if(box->text == NULL || box->state & VN_TEXTBOX_STATE_CLOSED) return;
diff --git a/src/vn/ui/vntextbox.h b/src/vn/ui/vntextbox.h
index e5879f3d..2789c843 100644
--- a/src/vn/ui/vntextbox.h
+++ b/src/vn/ui/vntextbox.h
@@ -8,7 +8,7 @@
 #pragma once
 #include "../../libs.h"
 #include "../../display/primitive/primitive.h"
-#include "../../display/shader.h"
+#include "../../display/shaderprogram.h"
 #include "../../display/animation/timeline.h"
 #include "../../display/font.h"
 #include "../../display/primitive/quad.h"
@@ -97,7 +97,7 @@ void vnTextBoxUpdate(vntextbox_t *box, engine_t *engine);
  * @param x X position.
  * @param y Y position.
  */
-void vnTextBoxRender(vntextbox_t *box, shader_t *shader, float x, float y);
+void vnTextBoxRender(vntextbox_t *box, shaderprogram_t *shader, float x, float y);
 
 /**
  * Disposes a previously created Visual Novel Text Box.
diff --git a/src/vn/vncharacter.c b/src/vn/vncharacter.c
index feca9670..9b325f44 100644
--- a/src/vn/vncharacter.c
+++ b/src/vn/vncharacter.c
@@ -165,7 +165,7 @@ void vnCharacterLayerSetFrame(vncharacter_t *character, uint8_t l, uint8_t f) {
   );
 }
 
-void vnCharacterRender(vncharacter_t *character, shader_t *shader) {
+void vnCharacterRender(vncharacter_t *character, shaderprogram_t *shader) {
   shaderUsePositionAndScale(shader,
     character->x, character->y, character->z,
     character->pitch, character->yaw, character->roll,
diff --git a/src/vn/vncharacter.h b/src/vn/vncharacter.h
index c18f8c08..57f2e84e 100644
--- a/src/vn/vncharacter.h
+++ b/src/vn/vncharacter.h
@@ -10,7 +10,7 @@
 #include "../display/texture.h"
 #include "../display/tileset.h"
 #include "../display/primitive/primitive.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 #include "../display/primitive/quad.h"
 #include "../display/animation/animation.h"
 #include "../engine/engine.h"
@@ -58,6 +58,6 @@ uint8_t vnCharacterLayerAdd(vncharacter_t *character,
 void vnCharacterLayerSetFrame(vncharacter_t *character, uint8_t l, uint8_t f);
 
 void vnCharacterUpdate(vncharacter_t *character, engine_t *engine);
-void vnCharacterRender(vncharacter_t *character, shader_t *shader);
+void vnCharacterRender(vncharacter_t *character, shaderprogram_t *shader);
 
 void vnCharacterDispose(vncharacter_t *character);
\ No newline at end of file
diff --git a/src/vn/vnscene.c b/src/vn/vnscene.c
index 9e36a9ed..5ca6dcdd 100644
--- a/src/vn/vnscene.c
+++ b/src/vn/vnscene.c
@@ -47,7 +47,9 @@ void vnSceneDispose(vnscene_t *scene) {
   vnConversationDispose(&scene->conversation);
 }
 
-void vnSceneRenderWorld(vnscene_t *scene, engine_t *engine, shader_t *shader) {
+void vnSceneRenderWorld(
+  vnscene_t *scene, engine_t *engine, shaderprogram_t *shader
+) {
   // Adjust Camera Position.
   cameraLookAtStruct(&scene->camera, scene->cameraLook);
 
@@ -61,7 +63,7 @@ void vnSceneRenderWorld(vnscene_t *scene, engine_t *engine, shader_t *shader) {
   shaderUseCamera(shader, &scene->camera);
 }
 
-void vnSceneRenderCharacters(vnscene_t *scene, shader_t *shader) {
+void vnSceneRenderCharacters(vnscene_t *scene, shaderprogram_t *shader) {
   uint8_t i;
   
   // Render each character
@@ -70,7 +72,9 @@ void vnSceneRenderCharacters(vnscene_t *scene, shader_t *shader) {
   }
 }
 
-void vnSceneRenderGui(vnscene_t *scene, engine_t *engine, shader_t *shader) {
+void vnSceneRenderGui(
+  vnscene_t *scene, engine_t *engine, shaderprogram_t *shader
+) {
   // Do we need to update the width of the GUI element(s) ?
   if(engine->render.width != scene->conversation.textbox.widthMax) {
     scene->conversation.textbox.widthMax = engine->render.width;
diff --git a/src/vn/vnscene.h b/src/vn/vnscene.h
index 4b2f1c21..d946f0c6 100644
--- a/src/vn/vnscene.h
+++ b/src/vn/vnscene.h
@@ -11,7 +11,7 @@
 #include "conversation/vnconversation.h"
 #include "ui/vntextbox.h"
 #include "../display/camera.h"
-#include "../display/shader.h"
+#include "../display/shaderprogram.h"
 #include "../display/animation/timeline.h"
 #include "../display/animation/easing.h"
 #include "../util/math.h"
@@ -44,11 +44,15 @@ void vnSceneUpdate(vnscene_t *scene, engine_t *engine);
 
 void vnSceneDispose(vnscene_t *scene);
 
-void vnSceneRenderWorld(vnscene_t *scene, engine_t *engine, shader_t *shader);
+void vnSceneRenderWorld(
+  vnscene_t *scene, engine_t *engine, shaderprogram_t *shader
+);
 
-void vnSceneRenderCharacters(vnscene_t *scene, shader_t *shader);
+void vnSceneRenderCharacters(vnscene_t *scene, shaderprogram_t *shader);
 
-void vnSceneRenderGui(vnscene_t *scene, engine_t *engine, shader_t *shader);
+void vnSceneRenderGui(
+  vnscene_t *scene, engine_t *engine, shaderprogram_t *shader
+);
 
 void vnSceneLookAt(vnscene_t *scene,
   float x, float y, float z, float lookX, float lookY, float lookZ