Added IRenderable, removed shader programs and allow more nuanced control of render passes, UI items are now rendered same as other scene item components.

This commit is contained in:
2023-05-29 15:52:08 -07:00
parent 117262267c
commit 96dd33c6b8
30 changed files with 419 additions and 600 deletions

View File

@ -166,62 +166,18 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
auto renderTarget = camera->getRenderTarget(); auto renderTarget = camera->getRenderTarget();
assertNotNull(renderTarget); assertNotNull(renderTarget);
// Update shader parameter buffers with current knowledge
this->camera = camera;
// Get the list of things to render first. // Get the list of things to render first.
std::vector<struct ShaderPassItem> shaderPassItems; std::vector<struct ShaderPassItem> shaderPassItems;
// Meshes // Renderables
auto meshes = scene->findComponents<MeshRenderer>(); auto renderables = scene->findComponents<IRenderable>();
auto itMesh = meshes.begin(); auto itRenderables = renderables.begin();
while(itMesh != meshes.end()) { while(itRenderables != renderables.end()) {
// Get Mesh vectorAppend(&shaderPassItems, (*itRenderables)->getRenderPasses());
auto mesh = *itMesh; ++itRenderables;
assertNotNull(mesh);
assertNotNull(mesh->mesh);
// Make sure this mesh has a material
auto mat = mesh->item->getComponent<Material>();
assertNotNull(mat);
auto shader = mat->getShader();
assertNotNull(shader);
// Now get and validate the pass items for this material/shader
auto materialPassItems = shader->getPassItems(mesh->mesh, mat, camera);
itPassItem = materialPassItems.begin();
while(itPassItem != materialPassItems.end()) {
auto item = *itPassItem;
// Validate the pass
assertNotNull(item.mesh);
assertTrue(item.start >= 0);
assertTrue(item.count > 0 || item.count == -1);
assertNotNull(item.shaderProgram);
// Queue
shaderPassItems.push_back(item);
++itPassItem;
}
++itMesh;
}
// UI Elements
if(renderTarget == this->renderManager->getBackBuffer()) {
auto canvases = scene->findComponents<UICanvas>();
auto itCanvas = canvases.begin();
while(itCanvas != canvases.end()) {
auto canvas = *itCanvas;
glm::mat4 projection;
glm::mat4 view;
canvas->getProjectionAndView(&projection, &view);
auto renderables = canvas->item->findChildrenDeep<UIComponentRenderable>();
auto itChild = renderables.begin();
while(itChild != renderables.end()) {
vectorAppend(&shaderPassItems,(*itChild)->getPassItems(projection, view));
++itChild;
}
++itCanvas;
}
} }
// Debug Lines // Debug Lines
@ -261,7 +217,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
); );
// Now we've sorted everything! Let's actually start rendering. // Now we've sorted everything! Let's actually start rendering.
ShaderProgram *boundProgram = nullptr; Shader *boundShader = nullptr;
std::map<textureslot_t, Texture*> boundTextures; std::map<textureslot_t, Texture*> boundTextures;
// TODO: This will be editable! // TODO: This will be editable!
@ -277,9 +233,9 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
auto item = *itPassItem; auto item = *itPassItem;
// Bind the program. // Bind the program.
if(boundProgram != item.shaderProgram) { if(boundShader != item.shader) {
boundProgram = item.shaderProgram; boundShader = item.shader;
boundProgram->bind(); boundShader->bind();
} }
// Bind the textures to the slots // Bind the textures to the slots
@ -298,37 +254,37 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
// Now set each of the parameters. Nothing exciting here. // Now set each of the parameters. Nothing exciting here.
auto itColors = item.colorValues.begin(); auto itColors = item.colorValues.begin();
while(itColors != item.colorValues.end()) { while(itColors != item.colorValues.end()) {
item.shaderProgram->setColor(itColors->first, itColors->second); item.shader->setColor(itColors->first, itColors->second);
++itColors; ++itColors;
} }
auto itBool = item.boolValues.begin(); auto itBool = item.boolValues.begin();
while(itBool != item.boolValues.end()) { while(itBool != item.boolValues.end()) {
item.shaderProgram->setBoolean(itBool->first, itBool->second); item.shader->setBoolean(itBool->first, itBool->second);
++itBool; ++itBool;
} }
auto itMat = item.matrixValues.begin(); auto itMat = item.matrixValues.begin();
while(itMat != item.matrixValues.end()) { while(itMat != item.matrixValues.end()) {
item.shaderProgram->setMatrix(itMat->first, itMat->second); item.shader->setMatrix(itMat->first, itMat->second);
++itMat; ++itMat;
} }
auto itVec3 = item.vec3Values.begin(); auto itVec3 = item.vec3Values.begin();
while(itVec3 != item.vec3Values.end()) { while(itVec3 != item.vec3Values.end()) {
item.shaderProgram->setVector3(itVec3->first, itVec3->second); item.shader->setVector3(itVec3->first, itVec3->second);
++itVec3; ++itVec3;
} }
auto itText = item.textureValues.begin(); auto itText = item.textureValues.begin();
while(itText != item.textureValues.end()) { while(itText != item.textureValues.end()) {
item.shaderProgram->setTexture(itText->first, itText->second); item.shader->setTexture(itText->first, itText->second);
++itText; ++itText;
} }
auto itFloat = item.floatValues.begin(); auto itFloat = item.floatValues.begin();
while(itFloat != item.floatValues.end()) { while(itFloat != item.floatValues.end()) {
item.shaderProgram->setFloat(itFloat->first, itFloat->second); item.shader->setFloat(itFloat->first, itFloat->second);
++itFloat; ++itFloat;
} }

View File

@ -6,10 +6,10 @@
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "scene/components/display/Material.hpp" #include "scene/components/display/Material.hpp"
#include "scene/components/display/mesh/MeshRenderer.hpp"
#include "scene/components/display/Camera.hpp" #include "scene/components/display/Camera.hpp"
#include "scene/components/scene/SubSceneController.hpp" #include "scene/components/scene/SubSceneController.hpp"
#include "scene/components/ui/UIComponent.hpp" #include "scene/components/ui/UIComponent.hpp"
#include "display/shader/ShaderPass.hpp"
namespace Dawn { namespace Dawn {
class RenderManager; class RenderManager;
@ -21,6 +21,9 @@ namespace Dawn {
public: public:
RenderManager *renderManager; RenderManager *renderManager;
// Temporary hack
Camera *camera = nullptr;
/** /**
* Constructs a new RenderPipeline. Render Pipelines are my attempt to * Constructs a new RenderPipeline. Render Pipelines are my attempt to
* create both a flexible, but standard way to allow the individual games * create both a flexible, but standard way to allow the individual games

View File

@ -1,65 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/ShaderProgram.hpp"
#include "display/mesh/Mesh.hpp"
#include "display/_RenderManager.hpp"
namespace Dawn {
class Material;
class MeshRenderer;
class Camera;
struct ShaderPassItem {
ShaderProgram *shaderProgram = nullptr;
int32_t priority = 0;
Mesh *mesh;
int32_t start = 0;
int32_t count = -1;
float_t w = 0;
renderflag_t renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST;
enum MeshDrawMode drawMode = MESH_DRAW_MODE_TRIANGLES;
// Parameters
std::map<shaderparameter_t, struct Color> colorValues;
std::map<shaderparameter_t, bool_t> boolValues;
std::map<shaderparameter_t, glm::mat4> matrixValues;
std::map<shaderparameter_t, glm::vec3> vec3Values;
std::map<shaderparameter_t, textureslot_t> textureValues;
std::map<shaderparameter_t, float_t> floatValues;
// Textures
std::map<textureslot_t, Texture*> textureSlots;
};
class Shader {
public:
int32_t shaderId = -1;
int_fast16_t renderId = 0;
/**
* Compile all programs for this shader. This amy not remain forever as I
* may decide to allow shaders to share programs somehow. For now though
* this is clean enough.
*/
virtual void compile() = 0;
/**
* Returns the list of pass items to render for the given scene item.
*
* @param mesh Mesh Renderer for the scene item.
* @param material Material for the scene item.
* @param camera Camera for the scene.
* @return List of passes to render.
*/
virtual std::vector<struct ShaderPassItem> getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) = 0;
};
}

View File

@ -0,0 +1,33 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/Shader.hpp"
#include "display/mesh/Mesh.hpp"
namespace Dawn {
struct ShaderPassItem {
Shader *shader = nullptr;
int32_t priority = 0;
Mesh *mesh;
int32_t start = 0;
int32_t count = -1;
float_t w = 0;
renderflag_t renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST;
enum MeshDrawMode drawMode = MESH_DRAW_MODE_TRIANGLES;
// Parameters
std::map<shaderparameter_t, struct Color> colorValues;
std::map<shaderparameter_t, bool_t> boolValues;
std::map<shaderparameter_t, glm::mat4> matrixValues;
std::map<shaderparameter_t, glm::vec3> vec3Values;
std::map<shaderparameter_t, textureslot_t> textureValues;
std::map<shaderparameter_t, float_t> floatValues;
// Textures
std::map<textureslot_t, Texture*> textureSlots;
};
}

View File

@ -1,16 +1,26 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2023 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/mesh/Mesh.hpp"
#include "display/_RenderManager.hpp"
#include "display/Texture.hpp" #include "display/Texture.hpp"
#include "display/shader/ShaderParameterBuffer.hpp" #include "display/shader/ShaderParameterBuffer.hpp"
namespace Dawn { namespace Dawn {
template<typename T> template<typename T>
class IShaderProgram { class IShader {
public: public:
int32_t shaderId = -1;
int_fast16_t renderId = 0;
/**
* Compile all programs for this shader.
*/
virtual void compile() = 0;
/** /**
* Attaches the supplied shader as the current shader. * Attaches the supplied shader as the current shader.
*/ */
@ -72,5 +82,6 @@ namespace Dawn {
* @param Float to bind. * @param Float to bind.
*/ */
virtual void setFloat(T parameter, float_t value) = 0; virtual void setFloat(T parameter, float_t value) = 0;
}; };
} }

View File

@ -0,0 +1,20 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/Shader.hpp"
namespace Dawn {
class IRenderable {
public:
/**
* Returns the render passes for this renderable item, typically a scene
* item component, e.g. a Material or a UI Item.
*
* @return Array of renderable passes.
*/
virtual std::vector<struct ShaderPassItem> getRenderPasses() = 0;
};
}

View File

@ -6,9 +6,10 @@
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "display/shader/ShaderManager.hpp" #include "display/shader/ShaderManager.hpp"
#include "scene/components/display/IRenderable.hpp"
namespace Dawn { namespace Dawn {
class Material : public SceneItemComponent { class Material : public SceneItemComponent, public IRenderable {
public: public:
/** /**
* Material component constructor. * Material component constructor.
@ -16,12 +17,5 @@ namespace Dawn {
* @param item Scene Item this component belongs to. * @param item Scene Item this component belongs to.
*/ */
Material(SceneItem *item); Material(SceneItem *item);
/**
* Returns the shader that this material uses.
*
* @return Shader that belongs to this material.
*/
virtual Shader * getShader() = 0;
}; };
} }

View File

@ -25,12 +25,15 @@ float_t UIBorder::getContentHeight() {
return this->height; return this->height;
} }
std::vector<struct ShaderPassItem> UIBorder::getPassItems( std::vector<struct ShaderPassItem> UIBorder::getRenderPasses() {
glm::mat4 proj, glm::mat4 view glm::mat4 view, proj;
) { auto canvas = this->getCanvas();
assertNotNull(canvas);
canvas->getProjectionAndView(&proj, &view);
struct ShaderPassItem item; struct ShaderPassItem item;
auto shader = &getGame()->renderManager.uiShader->program; auto shader = getGame()->renderManager.uiShader;
item.shaderProgram = shader; item.shader = shader;
item.colorValues[shader->paramColor] = COLOR_WHITE; item.colorValues[shader->paramColor] = COLOR_WHITE;
item.matrixValues[shader->paramProjection] = proj; item.matrixValues[shader->paramProjection] = proj;
item.matrixValues[shader->paramView] = view; item.matrixValues[shader->paramView] = view;

View File

@ -24,9 +24,7 @@ namespace Dawn {
float_t getContentWidth() override; float_t getContentWidth() override;
float_t getContentHeight() override; float_t getContentHeight() override;
std::vector<struct ShaderPassItem> getPassItems( std::vector<struct ShaderPassItem> getRenderPasses() override;
glm::mat4 proj, glm::mat4 view
) override;
void onStart() override; void onStart() override;
}; };
} }

View File

@ -161,6 +161,17 @@ void UIComponent::calculateDimensions(
} }
} }
UICanvas * UIComponent::getCanvas() {
// TODO: Cache this on first hit.
auto parent = this->transform->getParent();
while(parent != nullptr) {
auto canvas = parent->item->getComponent<UICanvas>();
if(canvas != nullptr) return canvas;
parent = parent->getParent();
}
return nullptr;
}
float_t UIComponent::getWidth() { float_t UIComponent::getWidth() {
return this->width; return this->width;
} }

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "scene/components/display/IRenderable.hpp"
#include "UICanvas.hpp" #include "UICanvas.hpp"
#include "util/mathutils.hpp" #include "util/mathutils.hpp"
@ -21,7 +22,7 @@ namespace Dawn {
UI_COMPONENT_ALIGN_UNIT_PERCENT UI_COMPONENT_ALIGN_UNIT_PERCENT
}; };
class UIComponentRenderable { class UIComponentRenderable : public IRenderable {
public: public:
/** /**
* Implemented UI Components that have rendering should implement this and * Implemented UI Components that have rendering should implement this and
@ -32,10 +33,7 @@ namespace Dawn {
* @param view Camera view, obtained from the canvas. * @param view Camera view, obtained from the canvas.
* @return A list of renderable shader pass items for this renderable. * @return A list of renderable shader pass items for this renderable.
*/ */
virtual std::vector<struct ShaderPassItem> getPassItems( virtual std::vector<struct ShaderPassItem> getRenderPasses() = 0;
glm::mat4 projection,
glm::mat4 view
) = 0;
}; };
class UIComponent : public SceneItemComponent, public UIComponentDimensional { class UIComponent : public SceneItemComponent, public UIComponentDimensional {
@ -114,6 +112,13 @@ namespace Dawn {
UIComponent(SceneItem *item); UIComponent(SceneItem *item);
/**
* Returns the canvas that this UI element is belonging to.
*
* @return Pointer to the UI Canvas this component is a child of.
*/
UICanvas * getCanvas();
float_t getWidth() override; float_t getWidth() override;
float_t getHeight() override; float_t getHeight() override;
void onStart() override; void onStart() override;

View File

@ -25,12 +25,15 @@ float_t UIImage::getContentHeight() {
return this->height; return this->height;
} }
std::vector<struct ShaderPassItem> UIImage::getPassItems( std::vector<struct ShaderPassItem> UIImage::getRenderPasses() {
glm::mat4 proj, glm::mat4 view glm::mat4 view, proj;
) { auto canvas = this->getCanvas();
assertNotNull(canvas);
canvas->getProjectionAndView(&proj, &view);
struct ShaderPassItem item; struct ShaderPassItem item;
auto shader = &getGame()->renderManager.uiShader->program; auto shader = getGame()->renderManager.uiShader;
item.shaderProgram = shader; item.shader = shader;
item.colorValues[shader->paramColor] = this->color; item.colorValues[shader->paramColor] = this->color;
item.matrixValues[shader->paramProjection] = proj; item.matrixValues[shader->paramProjection] = proj;
item.matrixValues[shader->paramView] = view; item.matrixValues[shader->paramView] = view;

View File

@ -22,9 +22,7 @@ namespace Dawn {
float_t getContentWidth() override; float_t getContentWidth() override;
float_t getContentHeight() override; float_t getContentHeight() override;
std::vector<struct ShaderPassItem> getPassItems( std::vector<struct ShaderPassItem> getRenderPasses() override;
glm::mat4 proj, glm::mat4 view
) override;
void onStart() override; void onStart() override;
}; };
} }

View File

@ -67,15 +67,18 @@ void UILabel::updateMesh() {
this->eventFontRebuffered.invoke(); this->eventFontRebuffered.invoke();
} }
std::vector<struct ShaderPassItem> UILabel::getPassItems( std::vector<struct ShaderPassItem> UILabel::getRenderPasses() {
glm::mat4 proj, glm::mat4 view
) {
if(!this->hasText()) return {}; if(!this->hasText()) return {};
this->updateMesh(); this->updateMesh();
glm::mat4 view, proj;
auto canvas = this->getCanvas();
assertNotNull(canvas);
canvas->getProjectionAndView(&proj, &view);
struct ShaderPassItem item; struct ShaderPassItem item;
auto shader = &getGame()->renderManager.fontShader->program; auto shader = getGame()->renderManager.fontShader;
item.shaderProgram = shader; item.shader = shader;
item.colorValues[shader->paramColor] = textColor; item.colorValues[shader->paramColor] = textColor;
item.matrixValues[shader->paramProjection] = proj; item.matrixValues[shader->paramProjection] = proj;
item.matrixValues[shader->paramView] = view; item.matrixValues[shader->paramView] = view;

View File

@ -53,9 +53,7 @@ namespace Dawn {
float_t getContentWidth() override; float_t getContentWidth() override;
float_t getContentHeight() override; float_t getContentHeight() override;
std::vector<struct ShaderPassItem> getPassItems( std::vector<struct ShaderPassItem> getRenderPasses() override;
glm::mat4 projection, glm::mat4 view
) override;
void onStart() override; void onStart() override;
}; };
} }

View File

@ -9,7 +9,7 @@
#include "display/shader/ShaderManager.hpp" #include "display/shader/ShaderManager.hpp"
#include "display/shader/SimpleTexturedShader.hpp" #include "display/shader/SimpleTexturedShader.hpp"
#include "display/shader/FontShader.hpp" #include "display/shader/FontShader.hpp"
#include "display/shader/UIShaderProgram.hpp" #include "display/shader/UIShader.hpp"
#include "display/RenderPipeline.hpp" #include "display/RenderPipeline.hpp"
#include "display/font/FontManager.hpp" #include "display/font/FontManager.hpp"
#include "display/font/ExampleFont.hpp" #include "display/font/ExampleFont.hpp"

View File

@ -6,7 +6,7 @@
# Sources # Sources
target_sources(${DAWN_TARGET_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
ShaderProgram.cpp Shader.cpp
FontShader.cpp FontShader.cpp
SimpleTexturedShader.cpp SimpleTexturedShader.cpp
SimpleBillboardedShader.cpp SimpleBillboardedShader.cpp

View File

@ -4,12 +4,10 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "FontShader.hpp" #include "FontShader.hpp"
#include "scene/components/display/mesh/MeshRenderer.hpp"
#include "scene/components/display/Camera.hpp"
using namespace Dawn; using namespace Dawn;
void FontShaderProgram::compile() { void FontShader::compile() {
#if DAWN_OPENGL_GLSL #if DAWN_OPENGL_GLSL
this->compileShader( this->compileShader(
{ {
@ -53,17 +51,4 @@ void FontShaderProgram::compile() {
this->paramModel = this->getParameterByName("u_Model"); this->paramModel = this->getParameterByName("u_Model");
this->paramColor = this->getParameterByName("u_Color"); this->paramColor = this->getParameterByName("u_Color");
this->paramTexture = this->getParameterByName("u_Text"); this->paramTexture = this->getParameterByName("u_Text");
}
void FontShader::compile() {
this->program.compile();
}
std::vector<struct ShaderPassItem> FontShader::getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) {
std::vector<struct ShaderPassItem> passes;
return passes;
} }

View File

@ -10,10 +10,10 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/shader/ShaderManager.hpp" #include "display/shader/Shader.hpp"
namespace Dawn { namespace Dawn {
class FontShaderProgram : public ShaderProgram { class FontShader : public Shader {
public: public:
shaderparameter_t paramProjection; shaderparameter_t paramProjection;
shaderparameter_t paramView; shaderparameter_t paramView;
@ -23,17 +23,4 @@ namespace Dawn {
void compile() override; void compile() override;
}; };
class FontShader : public Shader {
public:
FontShaderProgram program;
void compile() override;
std::vector<struct ShaderPassItem> getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) override;
};
} }

View File

@ -1,129 +1,129 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "ShaderProgram.hpp" #include "Shader.hpp"
using namespace Dawn; using namespace Dawn;
void ShaderProgram::compileShader( void Shader::compileShader(
std::map<std::string, int32_t> attributeLocations, std::map<std::string, int32_t> attributeLocations,
std::string vertexShader, std::string vertexShader,
std::string fragmentShader std::string fragmentShader
) { ) {
GLint isSuccess; GLint isSuccess;
int32_t maxLength; int32_t maxLength;
char error[1024]; char error[1024];
// Load the vertex shader first // Load the vertex shader first
this->shaderVertex = glCreateShader(GL_VERTEX_SHADER); this->shaderVertex = glCreateShader(GL_VERTEX_SHADER);
auto vertShaderC = vertexShader.c_str(); auto vertShaderC = vertexShader.c_str();
glShaderSource(this->shaderVertex, 1, &vertShaderC, 0); glShaderSource(this->shaderVertex, 1, &vertShaderC, 0);
glCompileShader(this->shaderVertex); glCompileShader(this->shaderVertex);
// Validate // Validate
glGetShaderiv(this->shaderVertex, GL_COMPILE_STATUS, &isSuccess); glGetShaderiv(this->shaderVertex, GL_COMPILE_STATUS, &isSuccess);
if(!isSuccess) { if(!isSuccess) {
glGetShaderiv(this->shaderVertex, GL_INFO_LOG_LENGTH, &maxLength); glGetShaderiv(this->shaderVertex, GL_INFO_LOG_LENGTH, &maxLength);
glGetShaderInfoLog(this->shaderVertex, maxLength, &maxLength, error); glGetShaderInfoLog(this->shaderVertex, maxLength, &maxLength, error);
debugMessage("Error compiling vert shader"); debugMessage("Error compiling vert shader");
debugMessage(error); debugMessage(error);
throw error; throw error;
} }
// Now load the Frag shader // Now load the Frag shader
this->shaderFrag = glCreateShader(GL_FRAGMENT_SHADER); this->shaderFrag = glCreateShader(GL_FRAGMENT_SHADER);
auto fragShaderC = fragmentShader.c_str(); auto fragShaderC = fragmentShader.c_str();
glShaderSource(this->shaderFrag, 1, &fragShaderC, 0); glShaderSource(this->shaderFrag, 1, &fragShaderC, 0);
glCompileShader(this->shaderFrag); glCompileShader(this->shaderFrag);
glGetShaderiv(this->shaderFrag, GL_COMPILE_STATUS, &isSuccess); glGetShaderiv(this->shaderFrag, GL_COMPILE_STATUS, &isSuccess);
if(!isSuccess) { if(!isSuccess) {
glGetShaderiv(this->shaderFrag, GL_INFO_LOG_LENGTH, &maxLength); glGetShaderiv(this->shaderFrag, GL_INFO_LOG_LENGTH, &maxLength);
glGetShaderInfoLog(this->shaderFrag, maxLength, &maxLength, error); glGetShaderInfoLog(this->shaderFrag, maxLength, &maxLength, error);
glDeleteShader(this->shaderVertex); glDeleteShader(this->shaderVertex);
debugMessage("Error compiling frag shader"); debugMessage("Error compiling frag shader");
debugMessage(error); debugMessage(error);
throw error; throw error;
} }
// Now create the shader program. // Now create the shader program.
this->shaderProgram = glCreateProgram(); this->shaderProgram = glCreateProgram();
glAttachShader(this->shaderProgram, this->shaderVertex); glAttachShader(this->shaderProgram, this->shaderVertex);
glAttachShader(this->shaderProgram, this->shaderFrag); glAttachShader(this->shaderProgram, this->shaderFrag);
// Now parse out the variables. // Now parse out the variables.
#if DAWN_OPENGL_HLSL #if DAWN_OPENGL_HLSL
auto itAttr = attributeLocations.begin(); auto itAttr = attributeLocations.begin();
while(itAttr != attributeLocations.end()) { while(itAttr != attributeLocations.end()) {
this->bindAttributeLocation(itAttr->first, itAttr->second); this->bindAttributeLocation(itAttr->first, itAttr->second);
++itAttr; ++itAttr;
} }
#endif #endif
//Bind, Verify & Use the shader program //Bind, Verify & Use the shader program
glLinkProgram(this->shaderProgram); glLinkProgram(this->shaderProgram);
glGetProgramiv(this->shaderProgram, GL_LINK_STATUS, &isSuccess); glGetProgramiv(this->shaderProgram, GL_LINK_STATUS, &isSuccess);
if(!isSuccess) { if(!isSuccess) {
glGetProgramiv(this->shaderProgram, GL_INFO_LOG_LENGTH, &maxLength); glGetProgramiv(this->shaderProgram, GL_INFO_LOG_LENGTH, &maxLength);
glGetProgramInfoLog(this->shaderProgram, maxLength, &maxLength, error); glGetProgramInfoLog(this->shaderProgram, maxLength, &maxLength, error);
glDeleteShader(this->shaderVertex); glDeleteShader(this->shaderVertex);
glDeleteShader(this->shaderFrag); glDeleteShader(this->shaderFrag);
debugMessage("Error compiling shader program"); debugMessage("Error compiling shader program");
debugMessage(error); debugMessage(error);
throw error; throw error;
} }
} }
void ShaderProgram::bindAttributeLocation(std::string name, int32_t location) { void Shader::bindAttributeLocation(std::string name, int32_t location) {
if(this->shaderProgram == -1) throw "Shader has not yet been compiled"; if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
glBindAttribLocation(this->shaderProgram, location, name.c_str()); glBindAttribLocation(this->shaderProgram, location, name.c_str());
} }
void ShaderProgram::setTexture(shaderparameter_t param, textureslot_t slot) { void Shader::setTexture(shaderparameter_t param, textureslot_t slot) {
glUniform1i(param, slot); glUniform1i(param, slot);
} }
shaderparameter_t ShaderProgram::getParameterByName(std::string name) { shaderparameter_t Shader::getParameterByName(std::string name) {
return glGetUniformLocation(this->shaderProgram, name.c_str()); return glGetUniformLocation(this->shaderProgram, name.c_str());
} }
shaderbufferlocation_t ShaderProgram::getBufferLocationByName(std::string name) { shaderbufferlocation_t Shader::getBufferLocationByName(std::string name) {
return glGetUniformBlockIndex(this->shaderProgram, name.c_str()); return glGetUniformBlockIndex(this->shaderProgram, name.c_str());
} }
void ShaderProgram::setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot) { void Shader::setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot) {
glUniformBlockBinding(this->shaderProgram, location, slot); glUniformBlockBinding(this->shaderProgram, location, slot);
} }
void ShaderProgram::setMatrix(shaderparameter_t uniform, glm::mat4 matrix) { void Shader::setMatrix(shaderparameter_t uniform, glm::mat4 matrix) {
glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(matrix)); glUniformMatrix4fv(uniform, 1, GL_FALSE, glm::value_ptr(matrix));
} }
void ShaderProgram::setBoolean(shaderparameter_t uni, bool value) { void Shader::setBoolean(shaderparameter_t uni, bool value) {
glUniform1i(uni, value); glUniform1i(uni, value);
} }
void ShaderProgram::setColor(shaderparameter_t uniform, struct Color color) { void Shader::setColor(shaderparameter_t uniform, struct Color color) {
auto precise = color.precision(); auto precise = color.precision();
glUniform4f(uniform, precise.r, precise.g, precise.b, precise.a); glUniform4f(uniform, precise.r, precise.g, precise.b, precise.a);
} }
void ShaderProgram::setVector3(shaderparameter_t uniform, glm::vec3 vector) { void Shader::setVector3(shaderparameter_t uniform, glm::vec3 vector) {
glUniform3f(uniform, vector.x, vector.y, vector.z); glUniform3f(uniform, vector.x, vector.y, vector.z);
} }
void ShaderProgram::setFloat(shaderparameter_t param, float_t value) { void Shader::setFloat(shaderparameter_t param, float_t value) {
glUniform1f(param, value); glUniform1f(param, value);
} }
void ShaderProgram::bind() { void Shader::bind() {
if(this->shaderProgram == -1) throw "Shader has not yet been compiled"; if(this->shaderProgram == -1) throw "Shader has not yet been compiled";
glUseProgram(this->shaderProgram); glUseProgram(this->shaderProgram);
} }
ShaderProgram::~ShaderProgram() { Shader::~Shader() {
if(this->shaderProgram != -1) glDeleteProgram(this->shaderProgram); if(this->shaderProgram != -1) glDeleteProgram(this->shaderProgram);
if(this->shaderVertex != -1) glDeleteShader(this->shaderVertex); if(this->shaderVertex != -1) glDeleteShader(this->shaderVertex);
if(this->shaderFrag != -1) glDeleteShader(this->shaderFrag); if(this->shaderFrag != -1) glDeleteShader(this->shaderFrag);
} }

View File

@ -1,89 +1,84 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/shader/_ShaderProgram.hpp" #include "display/shader/_Shader.hpp"
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "display/Color.hpp" #include "display/Color.hpp"
#include "debug/debug.hpp" #include "debug/debug.hpp"
#include "ShaderParameterBuffer.hpp" #include "ShaderParameterBuffer.hpp"
typedef GLuint shaderparameter_t; typedef GLuint shaderparameter_t;
namespace Dawn { namespace Dawn {
class ShaderProgram : public IShaderProgram<shaderparameter_t> { class Shader : public IShader<shaderparameter_t> {
private: private:
/** Pointer to an uploaded vertex shader program */ /** Pointer to an uploaded vertex shader program */
GLuint shaderVertex = -1; GLuint shaderVertex = -1;
/** Pointer to an uploaded fragment shader program */ /** Pointer to an uploaded fragment shader program */
GLuint shaderFrag = -1; GLuint shaderFrag = -1;
/** Pointer to an uploaded shader program linked */ /** Pointer to an uploaded shader program linked */
GLuint shaderProgram = -1; GLuint shaderProgram = -1;
protected: protected:
/** /**
* Compiles a GLSL/HLSL shader and stores it on the GPU, updates the * Compiles a GLSL/HLSL shader and stores it on the GPU, updates the
* underlying pointers for you. * underlying pointers for you.
* *
* @param vertexShader The string source of the vertex shader. * @param vertexShader The string source of the vertex shader.
* @param fragmentShader The string source of the fragment shader. * @param fragmentShader The string source of the fragment shader.
*/ */
void compileShader( void compileShader(
std::map<std::string, int32_t> attributeLocations, std::map<std::string, int32_t> attributeLocations,
std::string vertexShader, std::string vertexShader,
std::string fragmentShader std::string fragmentShader
); );
/** /**
* Typically HLSL only, this method allows you to specify where vbo * Typically HLSL only, this method allows you to specify where vbo
* attributes are bound. Typically 0 for positions, 1 for coordinates, * attributes are bound. Typically 0 for positions, 1 for coordinates,
* etc. * etc.
* *
* @param name Attribute name in the HLSL shader. * @param name Attribute name in the HLSL shader.
* @param location Index pointing to which location it is to be bound to. * @param location Index pointing to which location it is to be bound to.
*/ */
void bindAttributeLocation(std::string name, int32_t location); void bindAttributeLocation(std::string name, int32_t location);
public: public:
/** /**
* Locate a shader parameter by its name. * Locate a shader parameter by its name.
* *
* @param name Name of the parameter to get. * @param name Name of the parameter to get.
* @return The shader parameter. * @return The shader parameter.
*/ */
shaderparameter_t getParameterByName(std::string name); shaderparameter_t getParameterByName(std::string name);
/** /**
* Locate a shader buffer parameter set by its name. * Locate a shader buffer parameter set by its name.
* *
* @param name Name of the buffer to get. * @param name Name of the buffer to get.
* @return The shader buffer. * @return The shader buffer.
*/ */
shaderbufferlocation_t getBufferLocationByName(std::string name); shaderbufferlocation_t getBufferLocationByName(std::string name);
/** virtual void compile() = 0;
* Method to request that this shader be compiled and put on the GPU. This void bind() override;
* method should call the protected compileShader method. void setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot);
*/ void setMatrix(shaderparameter_t parameter, glm::mat4 matrix) override;
virtual void compile() = 0; void setBoolean(shaderparameter_t parameter, bool_t value) override;
void setColor(shaderparameter_t parameter, struct Color color) override;
void bind() override; void setVector3(shaderparameter_t parameter, glm::vec3 vector) override;
void setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot); void setTexture(shaderparameter_t parameter, textureslot_t texture) override;
void setMatrix(shaderparameter_t parameter, glm::mat4 matrix) override; void setFloat(shaderparameter_t parameter, float_t value) override;
void setBoolean(shaderparameter_t parameter, bool_t value) override;
void setColor(shaderparameter_t parameter, struct Color color) override; /**
void setVector3(shaderparameter_t parameter, glm::vec3 vector) override; * Destroys and deletes the shader from the GPU.
void setTexture(shaderparameter_t parameter, textureslot_t texture) override; */
void setFloat(shaderparameter_t parameter, float_t value) override; virtual ~Shader();
};
/**
* Destroys and deletes the shader from the GPU.
*/
virtual ~ShaderProgram();
};
} }

View File

@ -4,12 +4,10 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "SimpleBillboardedShader.hpp" #include "SimpleBillboardedShader.hpp"
#include "scene/components/display/mesh/MeshRenderer.hpp"
#include "scene/components/display/Camera.hpp"
using namespace Dawn; using namespace Dawn;
void SimpleBillboardedShaderProgram::compile() { void SimpleBillboardedShader::compile() {
#if DAWN_OPENGL_GLSL #if DAWN_OPENGL_GLSL
this->compileShader( this->compileShader(
{ {
@ -61,43 +59,4 @@ void SimpleBillboardedShaderProgram::compile() {
this->paramColor = this->getParameterByName("u_Color"); this->paramColor = this->getParameterByName("u_Color");
this->paramTexture = this->getParameterByName("u_Text"); this->paramTexture = this->getParameterByName("u_Text");
this->paramHasTexture = this->getParameterByName("u_HasTexture"); this->paramHasTexture = this->getParameterByName("u_HasTexture");
}
void SimpleBillboardedShader::compile() {
this->program.compile();
}
std::vector<struct ShaderPassItem> SimpleBillboardedShader::getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) {
auto simpleMaterial = dynamic_cast<SimpleBillboardedMaterial*>(material);
assertNotNull(simpleMaterial);
struct ShaderPassItem onlyPass;
onlyPass.mesh = mesh;
onlyPass.shaderProgram = &program;
onlyPass.colorValues[program.paramColor] = simpleMaterial->color;
onlyPass.matrixValues[program.paramModel] = material->transform->getWorldTransform();
onlyPass.matrixValues[program.paramView] = camera->transform->getWorldTransform();
onlyPass.matrixValues[program.paramProjection] = camera->getProjection();
onlyPass.renderFlags = (
RENDER_MANAGER_RENDER_FLAG_BLEND |
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
);
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 ShaderPassItem> passes;
passes.push_back(onlyPass);
return passes;
} }

View File

@ -4,10 +4,10 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "scene/components/display/material/SimpleBillboardedMaterial.hpp" #include "display/shader/Shader.hpp"
namespace Dawn { namespace Dawn {
class SimpleBillboardedShaderProgram : public ShaderProgram { class SimpleBillboardedShader : public Shader {
public: public:
shaderparameter_t paramProjection; shaderparameter_t paramProjection;
shaderparameter_t paramView; shaderparameter_t paramView;
@ -18,17 +18,4 @@ namespace Dawn {
void compile() override; void compile() override;
}; };
class SimpleBillboardedShader : public Shader {
public:
SimpleBillboardedShaderProgram program;
void compile() override;
std::vector<struct ShaderPassItem> getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) override;
};
} }

View File

@ -4,12 +4,10 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "SimpleTexturedShader.hpp" #include "SimpleTexturedShader.hpp"
#include "scene/components/display/mesh/MeshRenderer.hpp"
#include "scene/components/display/Camera.hpp"
using namespace Dawn; using namespace Dawn;
void SimpleTexturedShaderProgram::compile() { void SimpleTexturedShader::compile() {
#if DAWN_OPENGL_GLSL #if DAWN_OPENGL_GLSL
this->compileShader( this->compileShader(
{ {
@ -34,12 +32,6 @@ void SimpleTexturedShaderProgram::compile() {
// Fragment Shader // Fragment Shader
"#version 330 core\n" "#version 330 core\n"
"layout (std140) uniform uniTest {\n"
"float r;\n"
"float g;\n"
"float b;\n"
"};\n"
"in vec2 o_TextCoord;\n" "in vec2 o_TextCoord;\n"
"out vec4 o_Color;\n" "out vec4 o_Color;\n"
"uniform vec4 u_Color;\n" "uniform vec4 u_Color;\n"
@ -47,12 +39,11 @@ void SimpleTexturedShaderProgram::compile() {
"uniform sampler2D u_Text;\n" "uniform sampler2D u_Text;\n"
"void main() {\n" "void main() {\n"
// "if(u_HasTexture) {\n" "if(u_HasTexture) {\n"
// "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n" "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
// "} else {\n" "} else {\n"
// "o_Color = u_Color;" "o_Color = u_Color;"
// "}\n" "}\n"
"o_Color = vec4(r, g, b, 1);\n"
"}\n" "}\n"
); );
#elif DAWN_OPENGL_HLSL #elif DAWN_OPENGL_HLSL
@ -102,66 +93,4 @@ void SimpleTexturedShaderProgram::compile() {
this->paramColor = this->getParameterByName("u_Color"); this->paramColor = this->getParameterByName("u_Color");
this->paramTexture = this->getParameterByName("u_Text"); this->paramTexture = this->getParameterByName("u_Text");
this->paramHasTexture = this->getParameterByName("u_HasTexture"); this->paramHasTexture = this->getParameterByName("u_HasTexture");
this->test.init();
this->test.bind(0);
auto bufferLoc = this->getBufferLocationByName("uniTest");
this->setParameterBuffer(bufferLoc, 0);
struct Test123 data;
data.r = 1.0f;
data.g = 0.0f;
data.b = 1.0f;
this->test.buffer(&data);
data.g = 1.0f;
this->test.buffer(&data);
data.g = 0.0f;
data.b = 0.0f;
this->test.buffer(&data, &data.g);
data.g = 1.0f;
data.b = 0.0f;
this->test.buffer(&data, &data.g, &data.b);
}
void SimpleTexturedShader::compile() {
this->program.compile();
}
std::vector<struct ShaderPassItem> SimpleTexturedShader::getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) {
auto simpleMaterial = dynamic_cast<SimpleTexturedMaterial*>(material);
assertNotNull(simpleMaterial);
struct ShaderPassItem onlyPass;
onlyPass.mesh = mesh;
onlyPass.shaderProgram = &program;
onlyPass.colorValues[program.paramColor] = simpleMaterial->color;
onlyPass.matrixValues[program.paramModel] = material->transform->getWorldTransform();
onlyPass.matrixValues[program.paramView] = camera->transform->getWorldTransform();
onlyPass.matrixValues[program.paramProjection] = camera->getProjection();
onlyPass.renderFlags = (
RENDER_MANAGER_RENDER_FLAG_BLEND |
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
);
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 ShaderPassItem> passes;
passes.push_back(onlyPass);
return passes;
} }

View File

@ -4,24 +4,11 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/shader/ShaderManager.hpp" #include "display/shader/Shader.hpp"
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
#include "display/shader/ShaderParameterBuffer.hpp"
namespace Dawn { namespace Dawn {
struct Test123 { class SimpleTexturedShader : public Shader {
float_t r;
float_t g;
float_t b;
};
class SimpleTexturedShaderTest : public ShaderParameterBuffer<struct Test123> {
};
class SimpleTexturedShaderProgram : public ShaderProgram {
public: public:
SimpleTexturedShaderTest test;
shaderparameter_t paramProjection; shaderparameter_t paramProjection;
shaderparameter_t paramView; shaderparameter_t paramView;
shaderparameter_t paramModel; shaderparameter_t paramModel;
@ -31,17 +18,4 @@ namespace Dawn {
void compile() override; void compile() override;
}; };
class SimpleTexturedShader : public Shader {
public:
SimpleTexturedShaderProgram program;
void compile() override;
std::vector<struct ShaderPassItem> getPassItems(
Mesh *mesh,
Material *material,
Camera *camera
) override;
};
} }

View File

@ -1,14 +1,14 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "SimpleTexturedShader.hpp" #include "SimpleTexturedShader.hpp"
#define UI_SHADER_PROGRAM_PRIORITY 100 #define UI_SHADER_PROGRAM_PRIORITY 100
namespace Dawn { namespace Dawn {
class UIShaderProgram : public SimpleTexturedShaderProgram { class UIShader : public SimpleTexturedShader {
}; };
} }

View File

@ -22,6 +22,8 @@ void SimpleBillboardedMaterial::onDispose() {
this->getGame()->renderManager.getShaderManager()->releaseShader<SimpleBillboardedShader>(this->shaderLock); this->getGame()->renderManager.getShaderManager()->releaseShader<SimpleBillboardedShader>(this->shaderLock);
} }
Shader * SimpleBillboardedMaterial::getShader() { std::vector<struct ShaderPassItem> SimpleBillboardedMaterial::getRenderPasses() {
return this->getGame()->renderManager.getShaderManager()->getShader<SimpleBillboardedShader>(this->shaderLock); return {
};
} }

View File

@ -26,7 +26,6 @@ namespace Dawn {
void onStart() override; void onStart() override;
void onDispose() override; void onDispose() override;
std::vector<struct ShaderPassItem> getRenderPasses() override;
Shader * getShader() override;
}; };
} }

View File

@ -21,6 +21,37 @@ void SimpleTexturedMaterial::onDispose() {
this->getGame()->renderManager.getShaderManager()->releaseShader<SimpleTexturedShader>(this->shaderLock); this->getGame()->renderManager.getShaderManager()->releaseShader<SimpleTexturedShader>(this->shaderLock);
} }
Shader * SimpleTexturedMaterial::getShader() { std::vector<struct ShaderPassItem> SimpleTexturedMaterial::getRenderPasses() {
return this->getGame()->renderManager.getShaderManager()->getShader<SimpleTexturedShader>(this->shaderLock); auto mesh = this->item->getComponent<MeshRenderer>();
auto shader = this->getGame()->renderManager.getShaderManager()->getShader<SimpleTexturedShader>(this->shaderLock);
auto camera = this->getGame()->renderManager.getRenderPipeline()->camera;
assertNotNull(mesh);
assertNotNull(mesh->mesh);
assertNotNull(shader);
assertNotNull(camera);
struct ShaderPassItem onlyPass;
onlyPass.mesh = mesh->mesh;
onlyPass.shader = shader;
onlyPass.colorValues[shader->paramColor] = this->color;
onlyPass.matrixValues[shader->paramModel] = this->transform->getWorldTransform();
onlyPass.matrixValues[shader->paramView] = camera->transform->getWorldTransform();
onlyPass.matrixValues[shader->paramProjection] = camera->getProjection();
onlyPass.renderFlags = (
RENDER_MANAGER_RENDER_FLAG_BLEND |
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
);
if(this->texture != nullptr) {
onlyPass.boolValues[shader->paramHasTexture] = true;
onlyPass.textureSlots[0] = this->texture;
onlyPass.textureValues[shader->paramTexture] = 0;
} else {
onlyPass.boolValues[shader->paramHasTexture] = false;
}
std::vector<struct ShaderPassItem> passes;
passes.push_back(onlyPass);
return passes;
} }

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "scene/components/display/Material.hpp" #include "scene/components/display/Material.hpp"
#include "scene/components/display/mesh/MeshRenderer.hpp"
namespace Dawn { namespace Dawn {
class SimpleTexturedMaterial : public Material { class SimpleTexturedMaterial : public Material {
@ -26,7 +27,6 @@ namespace Dawn {
void onStart() override; void onStart() override;
void onDispose() override; void onDispose() override;
std::vector<struct ShaderPassItem> getRenderPasses() override;
Shader * getShader() override;
}; };
} }