The fruits of my labor
This commit is contained in:
@ -73,6 +73,8 @@ void RenderPipeline::renderScene(Scene *scene) {
|
||||
}
|
||||
|
||||
void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
std::vector<struct ShaderPassItem>::iterator itPassItem;
|
||||
|
||||
assertNotNull(scene);
|
||||
assertNotNull(camera);
|
||||
|
||||
@ -80,8 +82,12 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
// not sending parameters to shaders more than we need.
|
||||
this->renderId--;
|
||||
|
||||
// Get the render target.
|
||||
auto renderTarget = camera->getRenderTarget();
|
||||
assertNotNull(renderTarget);
|
||||
|
||||
// Get the list of things to render first.
|
||||
std::vector<struct RenderPipelineItem> pipelineItems;
|
||||
std::vector<struct ShaderPassItem> shaderPassItems;
|
||||
|
||||
// Meshes
|
||||
auto meshes = scene->findComponents<MeshRenderer>();
|
||||
@ -89,6 +95,7 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
while(itMesh != meshes.end()) {
|
||||
// Get Mesh
|
||||
auto mesh = *itMesh;
|
||||
assertNotNull(mesh);
|
||||
assertNotNull(mesh->mesh);
|
||||
|
||||
// Make sure this mesh has a material
|
||||
@ -98,62 +105,76 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
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;
|
||||
// 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.pass.shaderProgram);
|
||||
|
||||
// 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;
|
||||
}
|
||||
assertNotNull(item.mesh);
|
||||
assertTrue(item.start >= 0);
|
||||
assertTrue(item.count > 0 || item.count == -1);
|
||||
assertNotNull(item.shaderProgram);
|
||||
|
||||
// Queue
|
||||
pipelineItems.push_back(item);
|
||||
++itPass;
|
||||
shaderPassItems.push_back(item);
|
||||
++itPassItem;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// UI Elements
|
||||
auto canvases = scene->findComponents<UICanvas>();
|
||||
auto itCanvas = canvases.begin();
|
||||
while(itCanvas != canvases.end()) {
|
||||
auto canvas = *itCanvas;
|
||||
glm::mat4 model;
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
|
||||
// TODO: Get UI stuff here.
|
||||
switch(canvas->drawType) {
|
||||
case UI_DRAW_TYPE_WORLD_ABSOLUTE:
|
||||
projection = camera->projection;
|
||||
view = camera->transform->getWorldTransform();
|
||||
model = canvas->transform->getWorldTransform();
|
||||
break;
|
||||
|
||||
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
||||
projection = glm::ortho(0.0f, renderTarget->getWidth(), renderTarget->getHeight(), 0.0f);
|
||||
view = glm::mat4(1.0f);
|
||||
model = canvas->transform->getWorldTransform();
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable();
|
||||
}
|
||||
|
||||
auto itChild = canvas->children.begin();
|
||||
while(itChild != canvas->children.end()) {
|
||||
vectorAppend(&shaderPassItems, (*itChild)->getPassItems(
|
||||
projection, view, model
|
||||
));
|
||||
++itChild;
|
||||
}
|
||||
++itCanvas;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
shaderPassItems.begin(),
|
||||
shaderPassItems.end(),
|
||||
[](struct ShaderPassItem &a, struct ShaderPassItem &b){
|
||||
if(a.priority == b.priority) {
|
||||
return a.w < b.w;
|
||||
}
|
||||
return a.pass.orderShader < b.pass.orderShader;
|
||||
return a.priority < b.priority;
|
||||
}
|
||||
);
|
||||
|
||||
// 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();
|
||||
@ -161,24 +182,20 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
this->renderManager->setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND
|
||||
);
|
||||
|
||||
auto itItems = pipelineItems.begin();
|
||||
while(itItems != pipelineItems.end()) {
|
||||
auto item = *itItems;
|
||||
itPassItem = shaderPassItems.begin();
|
||||
while(itPassItem != shaderPassItems.end()) {
|
||||
auto item = *itPassItem;
|
||||
|
||||
// Bind the program.
|
||||
if(boundProgram != item.pass.shaderProgram) {
|
||||
boundProgram = item.pass.shaderProgram;
|
||||
if(boundProgram != item.shaderProgram) {
|
||||
boundProgram = item.shaderProgram;
|
||||
boundProgram->bind();
|
||||
}
|
||||
|
||||
// Bind the textures to the slots
|
||||
auto itTextureSlot = item.pass.textureSlots.begin();
|
||||
while(itTextureSlot != item.pass.textureSlots.end()) {
|
||||
auto itTextureSlot = item.textureSlots.begin();
|
||||
while(itTextureSlot != item.textureSlots.end()) {
|
||||
// Assert texture isn't null, just don't include it.
|
||||
assertNotNull(itTextureSlot->second);
|
||||
|
||||
@ -190,45 +207,52 @@ void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
}
|
||||
|
||||
// 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);
|
||||
auto itColors = item.colorValues.begin();
|
||||
while(itColors != item.colorValues.end()) {
|
||||
item.shaderProgram->setColor(itColors->first, itColors->second);
|
||||
++itColors;
|
||||
}
|
||||
|
||||
auto itBool = item.pass.boolValues.begin();
|
||||
while(itBool != item.pass.boolValues.end()) {
|
||||
item.pass.shaderProgram->setBoolean(itBool->first, itBool->second);
|
||||
auto itBool = item.boolValues.begin();
|
||||
while(itBool != item.boolValues.end()) {
|
||||
item.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);
|
||||
auto itMat = item.matrixValues.begin();
|
||||
while(itMat != item.matrixValues.end()) {
|
||||
item.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);
|
||||
auto itVec3 = item.vec3Values.begin();
|
||||
while(itVec3 != item.vec3Values.end()) {
|
||||
item.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);
|
||||
auto itText = item.textureValues.begin();
|
||||
while(itText != item.textureValues.end()) {
|
||||
item.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);
|
||||
auto itFloat = item.floatValues.begin();
|
||||
while(itFloat != item.floatValues.end()) {
|
||||
item.shaderProgram->setFloat(itFloat->first, itFloat->second);
|
||||
++itFloat;
|
||||
}
|
||||
|
||||
// Set Render flags
|
||||
this->renderManager->setRenderFlags(item.renderFlags);
|
||||
|
||||
// Thank god that's done, now just draw the damn mesh.
|
||||
item.mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
++itItems;
|
||||
item.mesh->draw(
|
||||
MESH_DRAW_MODE_TRIANGLES,
|
||||
item.start,
|
||||
item.count
|
||||
);
|
||||
++itPassItem;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,16 +10,11 @@
|
||||
#include "scene/components/display/Material.hpp"
|
||||
#include "scene/components/display/MeshRenderer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderManager;
|
||||
|
||||
struct RenderPipelineItem {
|
||||
MeshRenderer *mesh;
|
||||
struct ShaderPass pass;
|
||||
float_t w;
|
||||
};
|
||||
|
||||
class RenderPipeline {
|
||||
private:
|
||||
int_fast16_t renderId = -1;
|
||||
|
@ -5,13 +5,10 @@
|
||||
|
||||
#pragma once
|
||||
#include "RenderTarget.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/flag.hpp"
|
||||
|
||||
#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0)
|
||||
#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1)
|
||||
|
||||
typedef flag_t renderflag_t;
|
||||
|
||||
namespace Dawn {
|
||||
@ -51,13 +48,6 @@ namespace Dawn {
|
||||
* @return Reference to the currently active main scene render pipeline.
|
||||
*/
|
||||
virtual RenderPipeline * getRenderPipeline() = 0;
|
||||
|
||||
/**
|
||||
* Returns the UI Shader used by the game's UI engine.
|
||||
*
|
||||
* @return Pointer to the UI Shader.
|
||||
*/
|
||||
virtual UIShader * getUIShader() = 0;
|
||||
|
||||
/**
|
||||
* Sets the render flags for the render manager to use.
|
||||
|
@ -6,14 +6,21 @@
|
||||
#pragma once
|
||||
#include "display/shader/ShaderProgram.hpp"
|
||||
#include "scene/components/display/MeshRenderer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
#include "display/_RenderManager.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Material;
|
||||
|
||||
struct ShaderPass {
|
||||
struct ShaderPassItem {
|
||||
ShaderProgram *shaderProgram = nullptr;
|
||||
int32_t orderShader = 0;
|
||||
bool_t needsW = false;
|
||||
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;
|
||||
|
||||
// Parameters
|
||||
std::map<shaderparameter_t, struct Color> colorValues;
|
||||
@ -39,27 +46,17 @@ namespace Dawn {
|
||||
virtual void compile() = 0;
|
||||
|
||||
/**
|
||||
* Returns the list of passes to render for the given scene item.
|
||||
* 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 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
|
||||
virtual std::vector<struct ShaderPassItem> getPassItems(
|
||||
Mesh *mesh,
|
||||
Material *material,
|
||||
Camera *camera
|
||||
) = 0;
|
||||
};
|
||||
}
|
@ -4,6 +4,7 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIBorder.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
@ -20,6 +21,7 @@ void UIBorder::updatePositions() {
|
||||
glm::vec2 overallDimensions = glm::vec2(this->getWidth(), this->getHeight());
|
||||
glm::vec2 innerDimensions = overallDimensions - (this->edgeDimensions * 2.0f);
|
||||
|
||||
|
||||
// Top Left.
|
||||
QuadMesh::bufferQuadMesh(&this->mesh,
|
||||
glm::vec2(0, 0),
|
||||
@ -102,13 +104,25 @@ void UIBorder::updatePositions() {
|
||||
);
|
||||
}
|
||||
|
||||
void UIBorder::drawSelf(UIShader *shader, glm::mat4 transform) {
|
||||
if(this->texture == nullptr) return;
|
||||
std::vector<struct ShaderPassItem> UIBorder::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> items;
|
||||
if(this->texture == nullptr) return items;
|
||||
|
||||
shader->setUIColor(COLOR_WHITE);
|
||||
shader->setUIModel(transform);
|
||||
shader->setUITexture(this->texture);
|
||||
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
items.push_back(this->getGame()->renderManager.uiShaderProgram.getUIPassItem(
|
||||
projection,
|
||||
view,
|
||||
transform,
|
||||
this->texture,
|
||||
COLOR_WHITE,
|
||||
&this->mesh,
|
||||
this->z
|
||||
));
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void UIBorder::setBorderSize(glm::vec2 borderSize) {
|
||||
|
@ -17,7 +17,11 @@ namespace Dawn {
|
||||
glm::vec2 uv1 = glm::vec2(1.0f, 1.0f);
|
||||
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
Texture *texture = nullptr;
|
||||
|
@ -138,21 +138,29 @@ void UIComponent::setTransform(
|
||||
this->updatePositions();
|
||||
}
|
||||
|
||||
void UIComponent::draw(UIShader *uiShader, glm::mat4 parentTransform) {
|
||||
std::vector<struct ShaderPassItem> UIComponent::getPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 parent
|
||||
) {
|
||||
|
||||
// Calculate self transform matrix
|
||||
glm::mat4 selfTransform = parentTransform * glm::translate(
|
||||
glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z)
|
||||
glm::mat4 selfTransform = parent * glm::translate(
|
||||
glm::mat4(1.0f),
|
||||
glm::vec3(this->relativeX, this->relativeY, this->z)
|
||||
);
|
||||
|
||||
// Draw Self
|
||||
this->drawSelf(uiShader, selfTransform);
|
||||
auto items = this->getSelfPassItems(projection, view, selfTransform);
|
||||
|
||||
// Render children
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->draw(uiShader, selfTransform);
|
||||
vectorAppend(&items, (*it)->getPassItems(projection, view, selfTransform));
|
||||
++it;
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
void UIComponent::addChild(UIComponent *child) {
|
||||
|
@ -7,7 +7,9 @@
|
||||
#include "scene/components/ui/UICanvas.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/array.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum UIComponentAlign {
|
||||
@ -53,10 +55,16 @@ namespace Dawn {
|
||||
* Intended to be overwritten by subclass. Called by the draw method to
|
||||
* ask this child to draw.
|
||||
*
|
||||
* @param uiShader UI Shader for the child to use.
|
||||
* @param selfTransform Self alignment transform.
|
||||
* @param projection Projection matrix of the camera.
|
||||
* @param view View matrix of the camera.
|
||||
* @param parent Matrix of the parent of this UI item.
|
||||
* @return The list of shader pass items.
|
||||
*/
|
||||
virtual void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) = 0;
|
||||
virtual std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) = 0;
|
||||
|
||||
public:
|
||||
UICanvas *canvas;
|
||||
@ -136,7 +144,21 @@ namespace Dawn {
|
||||
float_t z
|
||||
);
|
||||
|
||||
void draw(UIShader *uiShader, glm::mat4 parentTransform);
|
||||
/**
|
||||
* Returns the list of renderable shader pass items for this UI element.
|
||||
* This is basically how you get your UI item to draw, this is called by
|
||||
* the RenderPipeline.
|
||||
*
|
||||
* @param projection Projection matrix of the camera.
|
||||
* @param view View matrix of the camera.
|
||||
* @param parent Matrix of the parent of this UI item.
|
||||
* @return The list of shader pass items, including children.
|
||||
*/
|
||||
std::vector<struct ShaderPassItem> getPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 parent
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a child to this UI Component.
|
||||
|
@ -11,6 +11,10 @@ UIEmpty::UIEmpty(UICanvas *canvas) : UIComponent(canvas) {
|
||||
|
||||
}
|
||||
|
||||
void UIEmpty::drawSelf(UIShader *shader, glm::mat4 selfTrans) {
|
||||
|
||||
std::vector<struct ShaderPassItem> UIEmpty::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
@ -8,8 +8,14 @@
|
||||
|
||||
namespace Dawn {
|
||||
class UIEmpty : public UIComponent {
|
||||
protected:
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
UIEmpty(UICanvas *canvas);
|
||||
void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) override;
|
||||
};
|
||||
}
|
@ -71,15 +71,29 @@ float_t UILabel::getContentHeight() {
|
||||
return this->measure.getHeight();
|
||||
}
|
||||
|
||||
void UILabel::drawSelf(UIShader *shader, glm::mat4 selfTransform) {
|
||||
if(this->font == nullptr || !this->hasText) return;
|
||||
std::vector<struct ShaderPassItem> UILabel::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> items;
|
||||
if(this->font == nullptr) return items;
|
||||
|
||||
// this has to go eventually
|
||||
this->updateMesh();
|
||||
shader->setUIColor(this->textColor);
|
||||
shader->setUIModel(selfTransform);
|
||||
shader->setUITexture(this->font->getTexture());
|
||||
|
||||
this->font->draw(&this->mesh, this->startQuad, this->quadCount);
|
||||
auto item = this->getGame()->renderManager.uiShaderProgram.getUIPassItem(
|
||||
projection,
|
||||
view,
|
||||
transform,
|
||||
this->font->getTexture(),
|
||||
this->textColor,
|
||||
&this->mesh,
|
||||
this->z
|
||||
);
|
||||
item.start = this->startQuad * QUAD_INDICE_COUNT;
|
||||
item.count = this->quadCount * QUAD_INDICE_COUNT;
|
||||
items.push_back(item);
|
||||
return items;
|
||||
}
|
||||
|
||||
void UILabel::setTransform(
|
||||
|
@ -23,6 +23,12 @@ namespace Dawn {
|
||||
/** Event for when the language strings are updated */
|
||||
void onLanguageUpdated();
|
||||
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
struct FontMeasure measure;
|
||||
int32_t startQuad = 0;
|
||||
@ -32,7 +38,6 @@ namespace Dawn {
|
||||
struct Color textColor = COLOR_MAGENTA;
|
||||
|
||||
UILabel(UICanvas *canvas);
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
virtual float_t getContentWidth() override;
|
||||
virtual float_t getContentHeight() override;
|
||||
void setTransform(
|
||||
|
@ -4,6 +4,7 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UISprite.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
@ -22,12 +23,21 @@ void UISprite::updatePositions() {
|
||||
);
|
||||
}
|
||||
|
||||
void UISprite::drawSelf(UIShader *uiShader, glm::mat4 selfTransform) {
|
||||
uiShader->setUITexture(nullptr);
|
||||
uiShader->setUIModel(selfTransform);
|
||||
uiShader->setUIModel(glm::mat4(1.0f));
|
||||
uiShader->setUIColor(this->color);
|
||||
uiShader->setUITexture(this->texture);
|
||||
std::vector<struct ShaderPassItem> UISprite::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
std::vector<struct ShaderPassItem> items;
|
||||
|
||||
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
items.push_back(this->getGame()->renderManager.uiShaderProgram.getUIPassItem(
|
||||
projection,
|
||||
view,
|
||||
transform,
|
||||
this->texture,
|
||||
this->color,
|
||||
&this->mesh,
|
||||
this->z
|
||||
));
|
||||
return items;
|
||||
}
|
@ -12,7 +12,11 @@ namespace Dawn {
|
||||
class UISprite : public UIComponent {
|
||||
protected:
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) override;
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
public:
|
||||
Mesh mesh;
|
||||
|
@ -4,6 +4,7 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "VisualNovelManager.hpp"
|
||||
#include "visualnovel/scene/SimpleVNScene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
@ -24,6 +25,13 @@ void VisualNovelManager::onStart() {
|
||||
assertNotNull(this->textBox);
|
||||
|
||||
this->getScene()->eventSceneUnpausedUpdate.addListener(this, &VisualNovelManager::onUnpausedUpdate);
|
||||
|
||||
// Handle queuing simple VN Manager
|
||||
auto scene = this->getScene();
|
||||
auto sceneAsSimple = dynamic_cast<SimpleVNScene*>(scene);
|
||||
if(sceneAsSimple != nullptr) {
|
||||
this->setEvent(sceneAsSimple->getVNEvent());
|
||||
}
|
||||
|
||||
if(this->currentEvent != nullptr) this->currentEvent->start(nullptr);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ SimpleVisualNovelBackground * SimpleVisualNovelBackground::create(Scene *s) {
|
||||
auto item = s->createSceneItem();
|
||||
// item->addComponent<MeshRenderer>();
|
||||
item->addComponent<MeshHost>();
|
||||
item->addComponent<Material>();
|
||||
item->addComponent<SimpleTexturedMaterial>();
|
||||
auto background = item->addComponent<SimpleVisualNovelBackground>();
|
||||
return background;
|
||||
}
|
||||
@ -24,14 +24,14 @@ SimpleVisualNovelBackground::SimpleVisualNovelBackground(SceneItem *item) :
|
||||
|
||||
std::vector<SceneItemComponent*> SimpleVisualNovelBackground::getDependencies(){
|
||||
return std::vector<SceneItemComponent*>{
|
||||
this->material = this->item->getComponent<Material>(),
|
||||
this->material = this->item->getComponent<SimpleTexturedMaterial>(),
|
||||
this->meshHost = this->item->getComponent<MeshHost>()
|
||||
};
|
||||
}
|
||||
|
||||
void SimpleVisualNovelBackground::setTexture(Texture *texture) {
|
||||
auto param = this->material->getShader()->getParameterByName("u_Text");
|
||||
this->material->textureValues[param] = texture;
|
||||
assertNotNull(texture);
|
||||
this->material->texture = texture;
|
||||
|
||||
// Since we go both negative and positive, actual height is doubled
|
||||
float_t aspect = (float_t)texture->getWidth() / (float_t)texture->getHeight();
|
||||
|
@ -5,11 +5,12 @@
|
||||
|
||||
#pragma once
|
||||
#include "scene/components/Components.hpp"
|
||||
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SimpleVisualNovelBackground : public SceneItemComponent {
|
||||
public:
|
||||
Material *material;
|
||||
SimpleTexturedMaterial *material;
|
||||
MeshHost *meshHost;
|
||||
|
||||
/**
|
||||
|
@ -12,17 +12,12 @@ VisualNovelCharacter::VisualNovelCharacter(SceneItem *item) :
|
||||
{
|
||||
}
|
||||
|
||||
void VisualNovelCharacter::setOpacity(float_t opacity) {
|
||||
auto interface = this->item->getComponent<SimpleTexturedShaderInterface>();
|
||||
assertNotNull(interface);
|
||||
auto color = interface->getColor();
|
||||
color.a = opacity;
|
||||
interface->setColor(color);
|
||||
std::vector<SceneItemComponent*> VisualNovelCharacter::getDependencies() {
|
||||
return std::vector<SceneItemComponent*>{
|
||||
(this->material = this->item->getComponent<SimpleTexturedMaterial>())
|
||||
};
|
||||
}
|
||||
|
||||
float_t VisualNovelCharacter::getOpacity() {
|
||||
auto interface = this->item->getComponent<SimpleTexturedShaderInterface>();
|
||||
assertNotNull(interface);
|
||||
auto color = interface->getColor();
|
||||
return color.a;
|
||||
void VisualNovelCharacter::onStart() {
|
||||
assertNotNull(this->material);
|
||||
}
|
@ -5,15 +5,13 @@
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "scene/components/display/shader/SimpleTexturedShaderInterface.hpp"
|
||||
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class VisualNovelCharacter : public SceneItemComponent {
|
||||
protected:
|
||||
SimpleTexturedShaderInterface *shaderInterface = nullptr;
|
||||
|
||||
public:
|
||||
std::string nameKey = "character.unknown";
|
||||
SimpleTexturedMaterial *material = nullptr;
|
||||
|
||||
/**
|
||||
* Visual Novel Character Component. Mostly logic-less but provides nice
|
||||
@ -23,10 +21,7 @@ namespace Dawn {
|
||||
*/
|
||||
VisualNovelCharacter(SceneItem *item);
|
||||
|
||||
SimpleTexturedShaderInterface * getShaderInterface();
|
||||
|
||||
void setOpacity(float_t opacity);
|
||||
|
||||
float_t getOpacity();
|
||||
std::vector<SceneItemComponent*> getDependencies() override;
|
||||
void onStart() override;
|
||||
};
|
||||
}
|
@ -13,17 +13,16 @@ VisualNovelFadeCharacterEvent::VisualNovelFadeCharacterEvent(
|
||||
bool_t fadeIn,
|
||||
easefunction_t *ease,
|
||||
float_t duration
|
||||
) : VisualNovelSimpleCallbackAnimationEvent<float_t, VisualNovelCharacter>(man)
|
||||
{
|
||||
this->callbackAnimation.easing = ease;
|
||||
this->callbackAnimation.setCallback(
|
||||
character, &VisualNovelCharacter::setOpacity
|
||||
);
|
||||
) : VisualNovelSimpleAnimationEvent<float_t>(
|
||||
man,
|
||||
&character->material->color.a
|
||||
) {
|
||||
this->simpleAnimation.easing = ease;
|
||||
if(fadeIn) {
|
||||
this->callbackAnimation.addKeyframe(0.0f, 0.0f);
|
||||
this->callbackAnimation.addKeyframe(duration, 1.0f);
|
||||
this->simpleAnimation.addKeyframe(0.0f, 0.0f);
|
||||
this->simpleAnimation.addKeyframe(duration, 1.0f);
|
||||
} else {
|
||||
this->callbackAnimation.addKeyframe(0.0f, 1.0f);
|
||||
this->callbackAnimation.addKeyframe(duration, 0.0f);
|
||||
this->simpleAnimation.addKeyframe(0.0f, 1.0f);
|
||||
this->simpleAnimation.addKeyframe(duration, 0.0f);
|
||||
}
|
||||
}
|
@ -4,13 +4,13 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "visualnovel/events/animation/VisualNovelSimpleCallbackAnimationEvent.hpp"
|
||||
#include "visualnovel/events/animation/VisualNovelSimpleAnimationEvent.hpp"
|
||||
#include "visualnovel/components/VisualNovelCharacter.hpp"
|
||||
#include "scene/components/display/Material.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class VisualNovelFadeCharacterEvent :
|
||||
public VisualNovelSimpleCallbackAnimationEvent<float_t,VisualNovelCharacter>
|
||||
public VisualNovelSimpleAnimationEvent<float_t>
|
||||
{
|
||||
public:
|
||||
VisualNovelFadeCharacterEvent(
|
||||
|
@ -37,21 +37,19 @@ void SimpleVNScene::stage() {
|
||||
auto listenerItem = this->createSceneItem();
|
||||
this->audioListener = listenerItem->addComponent<AudioListener>();
|
||||
|
||||
this->background = SimpleVisualNovelBackground::create(this);
|
||||
|
||||
// Stage VN Items
|
||||
this->vnStage();
|
||||
|
||||
// UI
|
||||
this->canvas = UICanvas::create(this);
|
||||
this->textbox = VisualNovelTextboxPrefab::create(this->canvas);
|
||||
this->background = SimpleVisualNovelBackground::create(this);
|
||||
|
||||
// VN Manager
|
||||
auto vnManagerItem = this->createSceneItem();
|
||||
this->vnManager = vnManagerItem->addComponent<VisualNovelManager>();
|
||||
|
||||
// Stage VN Items
|
||||
this->vnStage();
|
||||
|
||||
// Fader (Drawn over the top of everything else)
|
||||
this->vnFader = VisualNovelFader::create(canvas);
|
||||
|
||||
// Begin VN.
|
||||
this->vnManager->setEvent(this->getVNEvent());
|
||||
}
|
@ -27,8 +27,10 @@ namespace Dawn {
|
||||
VisualNovelManager *vnManager = nullptr;
|
||||
AudioListener *audioListener = nullptr;
|
||||
|
||||
/**
|
||||
* Internal method to stage the VN scene.
|
||||
*/
|
||||
virtual void vnStage() = 0;
|
||||
virtual IVisualNovelEvent * getVNEvent() = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
@ -41,5 +43,13 @@ namespace Dawn {
|
||||
|
||||
std::vector<Asset*> getRequiredAssets() override;
|
||||
void stage() override;
|
||||
|
||||
/**
|
||||
* Returns the first VN event for the scene. Called by the VN Manager for
|
||||
* simple scenes.
|
||||
*
|
||||
* @return First VN event to be queued.
|
||||
*/
|
||||
virtual IVisualNovelEvent * getVNEvent() = 0;
|
||||
};
|
||||
}
|
@ -138,8 +138,12 @@ int32_t VisualNovelTextbox::getCountOfVisibleLines() {
|
||||
return this->label.measure.getLineCount();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::drawSelf(UIShader *shader, glm::mat4 self) {
|
||||
|
||||
std::vector<struct ShaderPassItem> VisualNovelTextbox::getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) {
|
||||
return std::vector<struct ShaderPassItem>();
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::setFont(Font *font) {
|
||||
|
@ -25,7 +25,12 @@ namespace Dawn {
|
||||
VisualNovelCharacter *character = nullptr;
|
||||
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
|
||||
std::vector<struct ShaderPassItem> getSelfPassItems(
|
||||
glm::mat4 projection,
|
||||
glm::mat4 view,
|
||||
glm::mat4 transform
|
||||
) override;
|
||||
|
||||
/**
|
||||
* Listens for scene updates.
|
||||
|
Reference in New Issue
Block a user