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:
@ -166,62 +166,18 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
auto renderTarget = camera->getRenderTarget();
|
||||
assertNotNull(renderTarget);
|
||||
|
||||
// Update shader parameter buffers with current knowledge
|
||||
this->camera = camera;
|
||||
|
||||
// Get the list of things to render first.
|
||||
std::vector<struct ShaderPassItem> shaderPassItems;
|
||||
|
||||
// Meshes
|
||||
auto meshes = scene->findComponents<MeshRenderer>();
|
||||
auto itMesh = meshes.begin();
|
||||
while(itMesh != meshes.end()) {
|
||||
// Get Mesh
|
||||
auto mesh = *itMesh;
|
||||
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;
|
||||
}
|
||||
// Renderables
|
||||
auto renderables = scene->findComponents<IRenderable>();
|
||||
auto itRenderables = renderables.begin();
|
||||
while(itRenderables != renderables.end()) {
|
||||
vectorAppend(&shaderPassItems, (*itRenderables)->getRenderPasses());
|
||||
++itRenderables;
|
||||
}
|
||||
|
||||
// Debug Lines
|
||||
@ -261,7 +217,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
);
|
||||
|
||||
// Now we've sorted everything! Let's actually start rendering.
|
||||
ShaderProgram *boundProgram = nullptr;
|
||||
Shader *boundShader = nullptr;
|
||||
std::map<textureslot_t, Texture*> boundTextures;
|
||||
|
||||
// TODO: This will be editable!
|
||||
@ -277,9 +233,9 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
auto item = *itPassItem;
|
||||
|
||||
// Bind the program.
|
||||
if(boundProgram != item.shaderProgram) {
|
||||
boundProgram = item.shaderProgram;
|
||||
boundProgram->bind();
|
||||
if(boundShader != item.shader) {
|
||||
boundShader = item.shader;
|
||||
boundShader->bind();
|
||||
}
|
||||
|
||||
// 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.
|
||||
auto itColors = item.colorValues.begin();
|
||||
while(itColors != item.colorValues.end()) {
|
||||
item.shaderProgram->setColor(itColors->first, itColors->second);
|
||||
item.shader->setColor(itColors->first, itColors->second);
|
||||
++itColors;
|
||||
}
|
||||
|
||||
auto itBool = item.boolValues.begin();
|
||||
while(itBool != item.boolValues.end()) {
|
||||
item.shaderProgram->setBoolean(itBool->first, itBool->second);
|
||||
item.shader->setBoolean(itBool->first, itBool->second);
|
||||
++itBool;
|
||||
}
|
||||
|
||||
auto itMat = item.matrixValues.begin();
|
||||
while(itMat != item.matrixValues.end()) {
|
||||
item.shaderProgram->setMatrix(itMat->first, itMat->second);
|
||||
item.shader->setMatrix(itMat->first, itMat->second);
|
||||
++itMat;
|
||||
}
|
||||
|
||||
auto itVec3 = item.vec3Values.begin();
|
||||
while(itVec3 != item.vec3Values.end()) {
|
||||
item.shaderProgram->setVector3(itVec3->first, itVec3->second);
|
||||
item.shader->setVector3(itVec3->first, itVec3->second);
|
||||
++itVec3;
|
||||
}
|
||||
|
||||
auto itText = item.textureValues.begin();
|
||||
while(itText != item.textureValues.end()) {
|
||||
item.shaderProgram->setTexture(itText->first, itText->second);
|
||||
item.shader->setTexture(itText->first, itText->second);
|
||||
++itText;
|
||||
}
|
||||
|
||||
auto itFloat = item.floatValues.begin();
|
||||
while(itFloat != item.floatValues.end()) {
|
||||
item.shaderProgram->setFloat(itFloat->first, itFloat->second);
|
||||
item.shader->setFloat(itFloat->first, itFloat->second);
|
||||
++itFloat;
|
||||
}
|
||||
|
||||
|
@ -6,10 +6,10 @@
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "scene/components/display/Material.hpp"
|
||||
#include "scene/components/display/mesh/MeshRenderer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
#include "scene/components/scene/SubSceneController.hpp"
|
||||
#include "scene/components/ui/UIComponent.hpp"
|
||||
#include "display/shader/ShaderPass.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderManager;
|
||||
@ -21,6 +21,9 @@ namespace Dawn {
|
||||
public:
|
||||
RenderManager *renderManager;
|
||||
|
||||
// Temporary hack
|
||||
Camera *camera = nullptr;
|
||||
|
||||
/**
|
||||
* Constructs a new RenderPipeline. Render Pipelines are my attempt to
|
||||
* create both a flexible, but standard way to allow the individual games
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
33
src/dawn/display/shader/ShaderPass.hpp
Normal file
33
src/dawn/display/shader/ShaderPass.hpp
Normal 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;
|
||||
};
|
||||
}
|
@ -1,16 +1,26 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
#include "display/_RenderManager.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "display/shader/ShaderParameterBuffer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename T>
|
||||
class IShaderProgram {
|
||||
class IShader {
|
||||
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.
|
||||
*/
|
||||
@ -72,5 +82,6 @@ namespace Dawn {
|
||||
* @param Float to bind.
|
||||
*/
|
||||
virtual void setFloat(T parameter, float_t value) = 0;
|
||||
|
||||
};
|
||||
}
|
20
src/dawn/scene/components/display/IRenderable.hpp
Normal file
20
src/dawn/scene/components/display/IRenderable.hpp
Normal 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;
|
||||
};
|
||||
}
|
@ -6,9 +6,10 @@
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/shader/ShaderManager.hpp"
|
||||
#include "scene/components/display/IRenderable.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Material : public SceneItemComponent {
|
||||
class Material : public SceneItemComponent, public IRenderable {
|
||||
public:
|
||||
/**
|
||||
* Material component constructor.
|
||||
@ -16,12 +17,5 @@ namespace Dawn {
|
||||
* @param item Scene Item this component belongs to.
|
||||
*/
|
||||
Material(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Returns the shader that this material uses.
|
||||
*
|
||||
* @return Shader that belongs to this material.
|
||||
*/
|
||||
virtual Shader * getShader() = 0;
|
||||
};
|
||||
}
|
@ -25,12 +25,15 @@ float_t UIBorder::getContentHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIBorder::getPassItems(
|
||||
glm::mat4 proj, glm::mat4 view
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> UIBorder::getRenderPasses() {
|
||||
glm::mat4 view, proj;
|
||||
auto canvas = this->getCanvas();
|
||||
assertNotNull(canvas);
|
||||
canvas->getProjectionAndView(&proj, &view);
|
||||
|
||||
struct ShaderPassItem item;
|
||||
auto shader = &getGame()->renderManager.uiShader->program;
|
||||
item.shaderProgram = shader;
|
||||
auto shader = getGame()->renderManager.uiShader;
|
||||
item.shader = shader;
|
||||
item.colorValues[shader->paramColor] = COLOR_WHITE;
|
||||
item.matrixValues[shader->paramProjection] = proj;
|
||||
item.matrixValues[shader->paramView] = view;
|
||||
|
@ -24,9 +24,7 @@ namespace Dawn {
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
std::vector<struct ShaderPassItem> getPassItems(
|
||||
glm::mat4 proj, glm::mat4 view
|
||||
) override;
|
||||
std::vector<struct ShaderPassItem> getRenderPasses() override;
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
@ -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() {
|
||||
return this->width;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "scene/components/display/IRenderable.hpp"
|
||||
#include "UICanvas.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
@ -21,7 +22,7 @@ namespace Dawn {
|
||||
UI_COMPONENT_ALIGN_UNIT_PERCENT
|
||||
};
|
||||
|
||||
class UIComponentRenderable {
|
||||
class UIComponentRenderable : public IRenderable {
|
||||
public:
|
||||
/**
|
||||
* Implemented UI Components that have rendering should implement this and
|
||||
@ -32,10 +33,7 @@ namespace Dawn {
|
||||
* @param view Camera view, obtained from the canvas.
|
||||
* @return A list of renderable shader pass items for this renderable.
|
||||
*/
|
||||
virtual std::vector<struct ShaderPassItem> getPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view
|
||||
) = 0;
|
||||
virtual std::vector<struct ShaderPassItem> getRenderPasses() = 0;
|
||||
};
|
||||
|
||||
class UIComponent : public SceneItemComponent, public UIComponentDimensional {
|
||||
@ -114,6 +112,13 @@ namespace Dawn {
|
||||
|
||||
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 getHeight() override;
|
||||
void onStart() override;
|
||||
|
@ -25,12 +25,15 @@ float_t UIImage::getContentHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UIImage::getPassItems(
|
||||
glm::mat4 proj, glm::mat4 view
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> UIImage::getRenderPasses() {
|
||||
glm::mat4 view, proj;
|
||||
auto canvas = this->getCanvas();
|
||||
assertNotNull(canvas);
|
||||
canvas->getProjectionAndView(&proj, &view);
|
||||
|
||||
struct ShaderPassItem item;
|
||||
auto shader = &getGame()->renderManager.uiShader->program;
|
||||
item.shaderProgram = shader;
|
||||
auto shader = getGame()->renderManager.uiShader;
|
||||
item.shader = shader;
|
||||
item.colorValues[shader->paramColor] = this->color;
|
||||
item.matrixValues[shader->paramProjection] = proj;
|
||||
item.matrixValues[shader->paramView] = view;
|
||||
|
@ -22,9 +22,7 @@ namespace Dawn {
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
std::vector<struct ShaderPassItem> getPassItems(
|
||||
glm::mat4 proj, glm::mat4 view
|
||||
) override;
|
||||
std::vector<struct ShaderPassItem> getRenderPasses() override;
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
@ -67,15 +67,18 @@ void UILabel::updateMesh() {
|
||||
this->eventFontRebuffered.invoke();
|
||||
}
|
||||
|
||||
std::vector<struct ShaderPassItem> UILabel::getPassItems(
|
||||
glm::mat4 proj, glm::mat4 view
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> UILabel::getRenderPasses() {
|
||||
if(!this->hasText()) return {};
|
||||
this->updateMesh();
|
||||
|
||||
glm::mat4 view, proj;
|
||||
auto canvas = this->getCanvas();
|
||||
assertNotNull(canvas);
|
||||
canvas->getProjectionAndView(&proj, &view);
|
||||
|
||||
struct ShaderPassItem item;
|
||||
auto shader = &getGame()->renderManager.fontShader->program;
|
||||
item.shaderProgram = shader;
|
||||
auto shader = getGame()->renderManager.fontShader;
|
||||
item.shader = shader;
|
||||
item.colorValues[shader->paramColor] = textColor;
|
||||
item.matrixValues[shader->paramProjection] = proj;
|
||||
item.matrixValues[shader->paramView] = view;
|
||||
|
@ -53,9 +53,7 @@ namespace Dawn {
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
std::vector<struct ShaderPassItem> getPassItems(
|
||||
glm::mat4 projection, glm::mat4 view
|
||||
) override;
|
||||
std::vector<struct ShaderPassItem> getRenderPasses() override;
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user