Material update, before changing prefabs
This commit is contained in:
@ -5,14 +5,12 @@
|
||||
|
||||
#include "RenderPipeline.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
#include "display/RenderManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderManager *renderManager) {
|
||||
assertNotNull(renderManager);
|
||||
|
||||
this->renderManager = renderManager;
|
||||
}
|
||||
|
||||
@ -77,12 +75,84 @@ void RenderPipeline::renderScene(Scene *scene) {
|
||||
void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
assertNotNull(scene);
|
||||
assertNotNull(camera);
|
||||
|
||||
// Create a new render ID. Long story short this is a really dirty way of
|
||||
// not sending parameters to shaders more than we need.
|
||||
this->renderId++;
|
||||
|
||||
// Get the list of things to render first.
|
||||
std::vector<struct RenderPipelineItem> pipelineItems;
|
||||
|
||||
// Meshes
|
||||
auto meshes = scene->findComponents<MeshRenderer>();
|
||||
auto uiCanvasList = scene->findComponents<UICanvas>();
|
||||
auto itMesh = meshes.begin();
|
||||
while(itMesh != meshes.end()) {
|
||||
// Get Mesh
|
||||
auto mesh = *itMesh;
|
||||
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 do each pass.
|
||||
auto passes = shader->getItemPasses(mesh, mat);
|
||||
auto itPass = passes.begin();
|
||||
while(itPass != passes.end()) {
|
||||
struct RenderPipelineItem item;
|
||||
item.mesh = mesh;
|
||||
item.pass = *itPass;
|
||||
|
||||
// Do we need to get the W Vector?
|
||||
if(item.pass.needsW) {
|
||||
assertUnreachable();// TODO: Add distance from camera for W vector.
|
||||
} else {
|
||||
item.w = 0;
|
||||
}
|
||||
|
||||
// Queue
|
||||
pipelineItems.push_back(item);
|
||||
++itPass;
|
||||
}
|
||||
|
||||
// Now, for optimization, we bind the global parameters here, once for each
|
||||
// shader.
|
||||
if(shader->renderId != this->renderId) {
|
||||
shader->setGlobalParameters(
|
||||
camera->projection,
|
||||
camera->transform->getWorldTransform()
|
||||
);
|
||||
shader->renderId = this->renderId;
|
||||
}
|
||||
|
||||
++itMesh;
|
||||
}
|
||||
|
||||
// TODO: Get UI stuff here.
|
||||
|
||||
// Now we've queued everything, let's sort the rendering queue by the priority
|
||||
std::sort(
|
||||
pipelineItems.begin(),
|
||||
pipelineItems.end(),
|
||||
[](struct RenderPipelineItem &a, struct RenderPipelineItem &b){
|
||||
if(a.pass.orderShader == b.pass.orderShader) {
|
||||
return a.w < b.w;
|
||||
}
|
||||
return a.pass.orderShader < b.pass.orderShader;
|
||||
}
|
||||
);
|
||||
|
||||
// Now we've sorted everything! Let's actually start rendering.
|
||||
ShaderProgram *boundProgram = nullptr;
|
||||
std::map<textureslot_t, Texture*> boundTextures;
|
||||
|
||||
auto renderTarget = camera->getRenderTarget();
|
||||
|
||||
assertNotNull(renderTarget);
|
||||
|
||||
|
||||
// TODO: This will be editable!
|
||||
renderTarget->bind();
|
||||
renderTarget->clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
@ -92,92 +162,67 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND
|
||||
);
|
||||
|
||||
// Render all Meshes on the scene
|
||||
auto it = meshes.begin();
|
||||
while(it != meshes.end()) {
|
||||
auto mesh = *it;
|
||||
auto material = mesh->item->getComponent<Material>();
|
||||
|
||||
// TODO: fallback material?
|
||||
if(material == nullptr) {
|
||||
++it;
|
||||
continue;
|
||||
auto itItems = pipelineItems.begin();
|
||||
while(itItems != pipelineItems.end()) {
|
||||
auto item = *itItems;
|
||||
|
||||
// Bind the program.
|
||||
if(boundProgram != item.pass.shaderProgram) {
|
||||
boundProgram->bind();
|
||||
boundProgram = item.pass.shaderProgram;
|
||||
}
|
||||
|
||||
auto shader = material->getShader();
|
||||
assertNotNull(shader);
|
||||
shader->bind();
|
||||
shader->setGlobalParameters(camera->projection, camera->transform->getWorldTransform());
|
||||
shader->setMeshParameters(mesh->item->transform.getWorldTransform());
|
||||
material->setShaderParameters();
|
||||
|
||||
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
++it;
|
||||
}
|
||||
|
||||
|
||||
// Now we only render world-absolute UI canvas'
|
||||
auto uiShader = this->renderManager->getUIShader();
|
||||
assertNotNull(uiShader);
|
||||
uiShader->bind();
|
||||
uiShader->setUICamera(camera->projection, camera->transform->getWorldTransform());
|
||||
this->renderManager->setRenderFlags(RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST);
|
||||
|
||||
auto it2 = uiCanvasList.begin();
|
||||
while(it2 != uiCanvasList.end()) {
|
||||
auto canvas = *it2;
|
||||
|
||||
switch(canvas->drawType) {
|
||||
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
|
||||
break;
|
||||
|
||||
default:
|
||||
++it2;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto it3 = canvas->children.begin();
|
||||
auto rootMatrix = canvas->transform->getWorldTransform();
|
||||
while(it3 != canvas->children.end()) {
|
||||
(*it3)->draw(uiShader,
|
||||
glm::translate(glm::scale(rootMatrix, glm::vec3(1.0f, -1.0f, 1.0f)), glm::vec3(0, -renderTarget->getHeight(), 0))
|
||||
);
|
||||
++it3;
|
||||
}
|
||||
++it2;
|
||||
}
|
||||
|
||||
|
||||
// Now render camera-relative UI
|
||||
this->renderManager->setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND
|
||||
);
|
||||
uiShader->setUICamera(
|
||||
glm::ortho(0.0f, renderTarget->getWidth(), renderTarget->getHeight(), 0.0f),
|
||||
glm::mat4(1.0f)
|
||||
);
|
||||
|
||||
it2 = uiCanvasList.begin();
|
||||
while(it2 != uiCanvasList.end()) {
|
||||
auto canvas = *it2;
|
||||
|
||||
switch(canvas->drawType) {
|
||||
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
++it2;
|
||||
continue;
|
||||
// Bind the textures to the slots
|
||||
auto itTextureSlot = item.pass.textureSlots.begin();
|
||||
while(itTextureSlot != item.pass.textureSlots.end()) {
|
||||
if(boundTextures[itTextureSlot->first] != itTextureSlot->second) {
|
||||
itTextureSlot->second->bind(itTextureSlot->first);
|
||||
boundTextures[itTextureSlot->first] = itTextureSlot->second;
|
||||
}
|
||||
++itTextureSlot;
|
||||
}
|
||||
|
||||
auto it3 = canvas->children.begin();
|
||||
auto rootMatrix = canvas->transform->getWorldTransform();
|
||||
while(it3 != canvas->children.end()) {
|
||||
(*it3)->draw(uiShader, rootMatrix);
|
||||
++it3;
|
||||
// Now set each of the parameters. Nothing exciting here.
|
||||
auto itColors = item.pass.colorValues.begin();
|
||||
while(itColors != item.pass.colorValues.end()) {
|
||||
item.pass.shaderProgram->setColor(itColors->first, itColors->second);
|
||||
++itColors;
|
||||
}
|
||||
++it2;
|
||||
|
||||
auto itBool = item.pass.boolValues.begin();
|
||||
while(itBool != item.pass.boolValues.end()) {
|
||||
item.pass.shaderProgram->setBoolean(itBool->first, itBool->second);
|
||||
++itBool;
|
||||
}
|
||||
|
||||
auto itMat = item.pass.matrixValues.begin();
|
||||
while(itMat != item.pass.matrixValues.end()) {
|
||||
item.pass.shaderProgram->setMatrix(itMat->first, itMat->second);
|
||||
++itMat;
|
||||
}
|
||||
|
||||
auto itVec3 = item.pass.vec3Values.begin();
|
||||
while(itVec3 != item.pass.vec3Values.end()) {
|
||||
item.pass.shaderProgram->setVector3(itVec3->first, itVec3->second);
|
||||
++itVec3;
|
||||
}
|
||||
|
||||
auto itText = item.pass.textureValues.begin();
|
||||
while(itText != item.pass.textureValues.end()) {
|
||||
item.pass.shaderProgram->setTexture(itText->first, itText->second);
|
||||
++itText;
|
||||
}
|
||||
|
||||
auto itFloat = item.pass.floatValues.begin();
|
||||
while(itFloat != item.pass.floatValues.end()) {
|
||||
item.pass.shaderProgram->setFloat(itFloat->first, itFloat->second);
|
||||
++itFloat;
|
||||
}
|
||||
|
||||
// Thank god that's done, now just draw the damn mesh.
|
||||
item.mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
++itItems;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,14 +5,25 @@
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/RenderManager.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "scene/components/Components.hpp"
|
||||
#include "scene/components/ui/UICanvas.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "scene/components/display/Material.hpp"
|
||||
#include "scene/components/display/MeshRenderer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderManager;
|
||||
|
||||
struct RenderPipelineItem {
|
||||
MeshRenderer *mesh;
|
||||
struct ShaderPass pass;
|
||||
float_t w;
|
||||
};
|
||||
|
||||
class RenderPipeline {
|
||||
private:
|
||||
int_fast16_t renderId;
|
||||
|
||||
public:
|
||||
RenderManager *renderManager;
|
||||
|
||||
|
65
src/dawn/display/shader/Shader.hpp
Normal file
65
src/dawn/display/shader/Shader.hpp
Normal file
@ -0,0 +1,65 @@
|
||||
// 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 "scene/components/display/MeshRenderer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Material;
|
||||
|
||||
struct ShaderPass {
|
||||
ShaderProgram *shaderProgram;
|
||||
int32_t orderShader;
|
||||
bool_t needsW;
|
||||
|
||||
// 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:
|
||||
int_fast16_t renderId;
|
||||
|
||||
/**
|
||||
* 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 passes to render for the given scene item.
|
||||
*
|
||||
* @param mesh Mesh Renderer for the scene item.
|
||||
* @param material Material for the scene item.
|
||||
* @return List of passes to render.
|
||||
*/
|
||||
virtual std::vector<struct ShaderPass> getItemPasses(
|
||||
MeshRenderer *mesh,
|
||||
Material *material
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Called once per frame, set the global shader parameters that is used by
|
||||
* every item in the scene.
|
||||
*
|
||||
* @param cameraProjection Projection matrix of the camera.
|
||||
* @param cameraView View matrix of the camera.
|
||||
*/
|
||||
virtual void setGlobalParameters(
|
||||
glm::mat4 cameraProjection,
|
||||
glm::mat4 cameraView
|
||||
) = 0;
|
||||
};
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Material;
|
||||
|
||||
enum ShaderParameterType {
|
||||
SHADER_PARAMETER_TYPE_MATRIX,
|
||||
SHADER_PARAMETER_TYPE_BOOLEAN,
|
||||
SHADER_PARAMETER_TYPE_COLOR,
|
||||
SHADER_PARAMETER_TYPE_VECTOR3,
|
||||
SHADER_PARAMETER_TYPE_TEXTURE,
|
||||
SHADER_PARAMETER_TYPE_FLOAT
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class IShader {
|
||||
public:
|
||||
/**
|
||||
* Attaches the supplied shader as the current shader.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Requested by the Material to set the default parameters of the shader.
|
||||
* Each parameter really should have a default value set so that there is
|
||||
* no nullptr's or other issues.
|
||||
*
|
||||
* @param material Material to set the default parameters on to.
|
||||
*/
|
||||
virtual void setDefaultParameters(Material *material) = 0;
|
||||
|
||||
/**
|
||||
* Requested by the render pipeline (typically) to set global level (once
|
||||
* per frame) parameters.
|
||||
*
|
||||
* @param projection Projection matrix of the current viewport.
|
||||
* @param view View matrix of the current viewport.
|
||||
*/
|
||||
virtual void setGlobalParameters(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Requested by the render pipeline (typically) to set mesh-level params.
|
||||
* This may be performed multiple times per frame.
|
||||
*
|
||||
* @param position Matrix of the position of the mesh.
|
||||
*/
|
||||
virtual void setMeshParameters(glm::mat4 position) = 0;
|
||||
|
||||
/**
|
||||
* Retreives the list of all parameters that the shader supports. This
|
||||
* should not include the GLOBAL shader parameters (listed above) since
|
||||
* those will be modified by the engine directly.
|
||||
*
|
||||
* @return Key-Value-Pair of Shader parameters and their type.
|
||||
*/
|
||||
virtual std::map<T, enum ShaderParameterType> getParameters() = 0;
|
||||
|
||||
/**
|
||||
* Set's a specific shader parameter to a matrix.
|
||||
*
|
||||
* @param parameter parameter on the shader to set.
|
||||
* @param matrix Matrix to apply.
|
||||
*/
|
||||
virtual void setMatrix(T parameter, glm::mat4 matrix) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a boolean to a shader.
|
||||
*
|
||||
* @param parameter parameter to set.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
virtual void setBoolean(T parameter, bool_t value) = 0;
|
||||
|
||||
/**
|
||||
* Set a color on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the color to.
|
||||
* @param color Color to set.
|
||||
*/
|
||||
virtual void setColor(T parameter, struct Color color) = 0;
|
||||
|
||||
/**
|
||||
* Set a 3D vector on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the vector to.
|
||||
* @param vector Vector to set.
|
||||
*/
|
||||
virtual void setVector3(T parameter, glm::vec3 vector) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a texture to the currently bound shader.
|
||||
*
|
||||
* @param parameter parameter to set the texture on to.
|
||||
* @param texture Texture to bind to the parameter.
|
||||
*/
|
||||
virtual void setTexture(T parameter, Texture *texture) = 0;
|
||||
|
||||
/**
|
||||
* Sets a floating point value to the shader.
|
||||
*
|
||||
* @param parameter Paramater to set the float ont o.
|
||||
* @param Float to bind.
|
||||
*/
|
||||
virtual void setFloat(T parameter, float_t value) = 0;
|
||||
};
|
||||
}
|
76
src/dawn/display/shader/_ShaderProgram.hpp
Normal file
76
src/dawn/display/shader/_ShaderProgram.hpp
Normal file
@ -0,0 +1,76 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
// class Material;
|
||||
// enum ShaderParameterType {
|
||||
// SHADER_PARAMETER_TYPE_MATRIX,
|
||||
// SHADER_PARAMETER_TYPE_BOOLEAN,
|
||||
// SHADER_PARAMETER_TYPE_COLOR,
|
||||
// SHADER_PARAMETER_TYPE_VECTOR3,
|
||||
// SHADER_PARAMETER_TYPE_TEXTURE,
|
||||
// SHADER_PARAMETER_TYPE_FLOAT
|
||||
// };
|
||||
|
||||
template<typename T>
|
||||
class IShaderProgram {
|
||||
public:
|
||||
/**
|
||||
* Attaches the supplied shader as the current shader.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Set's a specific shader parameter to a matrix.
|
||||
*
|
||||
* @param parameter parameter on the shader to set.
|
||||
* @param matrix Matrix to apply.
|
||||
*/
|
||||
virtual void setMatrix(T parameter, glm::mat4 matrix) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a boolean to a shader.
|
||||
*
|
||||
* @param parameter parameter to set.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
virtual void setBoolean(T parameter, bool_t value) = 0;
|
||||
|
||||
/**
|
||||
* Set a color on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the color to.
|
||||
* @param color Color to set.
|
||||
*/
|
||||
virtual void setColor(T parameter, struct Color color) = 0;
|
||||
|
||||
/**
|
||||
* Set a 3D vector on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the vector to.
|
||||
* @param vector Vector to set.
|
||||
*/
|
||||
virtual void setVector3(T parameter, glm::vec3 vector) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a texture to the currently bound shader.
|
||||
*
|
||||
* @param parameter parameter to set the texture on to.
|
||||
* @param texture Texture slot to bind to the parameter.
|
||||
*/
|
||||
virtual void setTexture(T parameter, textureslot_t texture) = 0;
|
||||
|
||||
/**
|
||||
* Sets a floating point value to the shader.
|
||||
*
|
||||
* @param parameter Paramater to set the float ont o.
|
||||
* @param Float to bind.
|
||||
*/
|
||||
virtual void setFloat(T parameter, float_t value) = 0;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user