Stripped back old shader code for now.
This commit is contained in:
@@ -33,7 +33,6 @@ add_subdirectory(scene)
|
||||
add_subdirectory(settings)
|
||||
add_subdirectory(time)
|
||||
add_subdirectory(util)
|
||||
add_subdirectory(ui)
|
||||
|
||||
|
||||
# Assets
|
||||
|
||||
@@ -18,7 +18,7 @@ ShaderLoader::ShaderLoader(
|
||||
) :
|
||||
AssetLoader(assetManager, name),
|
||||
state(ShaderLoaderState::INITIAL),
|
||||
shader(std::make_shared<ShaderProgram2>())
|
||||
shader(std::make_shared<ShaderProgram>())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ void ShaderLoader::updateSync() {
|
||||
// Create the shader program.
|
||||
Slang::ComPtr<IBlob> blob;
|
||||
slang::ProgramLayout* layout = program->getLayout();
|
||||
std::vector<std::shared_ptr<ShaderEntry>> shaderEntries;
|
||||
std::vector<std::shared_ptr<ShaderStage>> shaderStages;
|
||||
for(auto i = 0; i < definedEntryPointCount; i++) {
|
||||
// Get the code
|
||||
auto result = linkedProgram->getEntryPointCode(
|
||||
@@ -95,18 +95,18 @@ void ShaderLoader::updateSync() {
|
||||
auto stage = entryPointReflection->getStage();
|
||||
|
||||
// Create the shader entry
|
||||
auto shaderEntry = std::make_shared<ShaderEntry>();
|
||||
shaderEntry->init(
|
||||
auto shaderStage = std::make_shared<ShaderStage>();
|
||||
shaderStage->init(
|
||||
stage,
|
||||
std::string((const char*)blob->getBufferPointer())
|
||||
);
|
||||
|
||||
// Add to the list
|
||||
shaderEntries.push_back(shaderEntry);
|
||||
shaderStages.push_back(shaderStage);
|
||||
}
|
||||
|
||||
// Create the shader program.
|
||||
shader->init(shaderEntries);
|
||||
shader->init(shaderStages);
|
||||
|
||||
// Finished loading.
|
||||
delete [] components;
|
||||
@@ -118,7 +118,7 @@ std::string ShaderLoader::getAssetType() const {
|
||||
return ShaderLoader::ASSET_TYPE;
|
||||
}
|
||||
|
||||
std::shared_ptr<IShaderProgram2> ShaderLoader::getShader() {
|
||||
std::shared_ptr<ShaderProgram> ShaderLoader::getShader() {
|
||||
assertNotNull(shader, "ShaderLoader shader is null.");
|
||||
return shader;
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "asset/AssetDataLoader.hpp"
|
||||
#include "display/shader/ShaderManager.hpp"
|
||||
#include "display/shader/ShaderProgram2.hpp"
|
||||
#include "display/shader/ShaderProgram.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderLoaderState {
|
||||
@@ -19,7 +19,7 @@ namespace Dawn {
|
||||
class ShaderLoader : public AssetLoader {
|
||||
protected:
|
||||
enum ShaderLoaderState state;
|
||||
std::shared_ptr<ShaderProgram2> shader;
|
||||
std::shared_ptr<ShaderProgram> shader;
|
||||
|
||||
public:
|
||||
const static std::string ASSET_TYPE;
|
||||
@@ -40,9 +40,9 @@ namespace Dawn {
|
||||
/**
|
||||
* Retreives the shader program for this loader.
|
||||
*
|
||||
* @return std::shared_ptr<IShaderProgram2>
|
||||
* @return The shader program that this loader is managing.
|
||||
*/
|
||||
std::shared_ptr<IShaderProgram2> getShader();
|
||||
std::shared_ptr<ShaderProgram> getShader();
|
||||
|
||||
~ShaderLoader();
|
||||
};
|
||||
|
||||
@@ -9,5 +9,4 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(ui)
|
||||
add_subdirectory(display)
|
||||
@@ -17,7 +17,7 @@ namespace Dawn {
|
||||
* @param ctx Context for the render pass.
|
||||
* @return List of render passes.
|
||||
*/
|
||||
virtual std::vector<std::shared_ptr<IRenderPass>> getPasses(
|
||||
virtual std::vector<std::shared_ptr<RenderPass>> getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) = 0;
|
||||
};
|
||||
@@ -31,26 +31,26 @@ namespace Dawn {
|
||||
* @param data Data to use for the render pass.
|
||||
* @return Created render pass.
|
||||
*/
|
||||
template<class S, typename D>
|
||||
std::shared_ptr<IRenderPass> createRenderPass(
|
||||
SceneComponent &self,
|
||||
const D data,
|
||||
const std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures = {},
|
||||
const std::shared_ptr<Mesh> mesh = nullptr,
|
||||
const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES,
|
||||
int32_t indiceStart = 0,
|
||||
int32_t indiceCount = -1
|
||||
) {
|
||||
return std::make_shared<RenderPass<S,D>>(
|
||||
self,
|
||||
data,
|
||||
textures,
|
||||
mesh,
|
||||
drawMode,
|
||||
indiceStart,
|
||||
indiceCount
|
||||
);
|
||||
}
|
||||
// template<class S, typename D>
|
||||
// std::shared_ptr<IRenderPass> createRenderPass(
|
||||
// SceneComponent &self,
|
||||
// const D data,
|
||||
// const std::unordered_map<
|
||||
// shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
// > textures = {},
|
||||
// const std::shared_ptr<Mesh> mesh = nullptr,
|
||||
// const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES,
|
||||
// int32_t indiceStart = 0,
|
||||
// int32_t indiceCount = -1
|
||||
// ) {
|
||||
// return std::make_shared<RenderPass<S,D>>(
|
||||
// self,
|
||||
// data,
|
||||
// textures,
|
||||
// mesh,
|
||||
// drawMode,
|
||||
// indiceStart,
|
||||
// indiceCount
|
||||
// );
|
||||
// }
|
||||
}
|
||||
@@ -9,11 +9,7 @@
|
||||
using namespace Dawn;
|
||||
|
||||
void Material::onInit() {
|
||||
this->lockedShaders = this->getLockedShaders(
|
||||
getGame()->renderHost->shaderManager
|
||||
);
|
||||
}
|
||||
|
||||
void Material::onDispose() {
|
||||
this->lockedShaders.clear();
|
||||
}
|
||||
@@ -13,18 +13,8 @@ namespace Dawn {
|
||||
public IRenderableComponent
|
||||
{
|
||||
private:
|
||||
std::vector<std::shared_ptr<IShaderBase>> lockedShaders;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Locks the shaders to be used for rendering.
|
||||
*
|
||||
* @param shaderManager Shader manager to use.
|
||||
* @return List of shaders to be used.
|
||||
*/
|
||||
virtual std::vector<std::shared_ptr<IShaderBase>> getLockedShaders(
|
||||
ShaderManager &shaderManager
|
||||
) = 0;
|
||||
|
||||
public:
|
||||
void onInit() override;
|
||||
|
||||
@@ -9,14 +9,6 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<
|
||||
std::shared_ptr<IShaderBase>
|
||||
> SimpleTexturedMaterial::getLockedShaders(ShaderManager &shaderManager) {
|
||||
return {
|
||||
shaderManager.getShader<SimpleTexturedShader>()
|
||||
};
|
||||
}
|
||||
|
||||
void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) {
|
||||
if(ctx->data.contains("color")) {
|
||||
this->setColor(JSON::color(ctx->data["color"]));
|
||||
@@ -31,7 +23,7 @@ void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) {
|
||||
}
|
||||
|
||||
struct Color SimpleTexturedMaterial::getColor() {
|
||||
return this->data.data.color;
|
||||
return this->data.color;
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() {
|
||||
@@ -45,32 +37,32 @@ void SimpleTexturedMaterial::setTexture(
|
||||
}
|
||||
|
||||
void SimpleTexturedMaterial::setColor(const struct Color color) {
|
||||
this->data.data.color = color;
|
||||
this->data.color = color;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> SimpleTexturedMaterial::getPasses(
|
||||
std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) {
|
||||
this->data.data.model = this->getItem()->getWorldTransform();
|
||||
this->data.data.projection = ctx.camera->getProjection();
|
||||
this->data.data.view = ctx.camera->getItem()->getWorldTransform();
|
||||
auto textures = std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
>();
|
||||
// this->data.model = this->getItem()->getWorldTransform();
|
||||
// this->data.projection = ctx.camera->getProjection();
|
||||
// this->data.view = ctx.camera->getItem()->getWorldTransform();
|
||||
// auto textures = std::unordered_map<
|
||||
// shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
// >();
|
||||
|
||||
if(this->texture) {
|
||||
this->data.data.hasTexture = true;
|
||||
this->data.texture = 0;
|
||||
textures[this->data.texture] = this->texture;
|
||||
} else {
|
||||
this->data.data.hasTexture = false;
|
||||
}
|
||||
// if(this->texture) {
|
||||
// this->data.hasTexture = true;
|
||||
// this->data.texture = 0;
|
||||
// textures[this->data.texture] = this->texture;
|
||||
// } else {
|
||||
// this->data.data.hasTexture = false;
|
||||
// }
|
||||
|
||||
return {
|
||||
createRenderPass<SimpleTexturedShader, struct SimpleTexturedShaderData>(
|
||||
*this,
|
||||
data,
|
||||
textures
|
||||
)
|
||||
// createRenderPass<SimpleTexturedShader, struct SimpleTexturedShaderData>(
|
||||
// *this,
|
||||
// data,
|
||||
// textures
|
||||
// )
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5,19 +5,24 @@
|
||||
|
||||
#pragma once
|
||||
#include "component/display/material/Material.hpp"
|
||||
#include "display/shader/SimpleTexturedShader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct SimpleTexturedMaterialShaderData {
|
||||
int32_t t;
|
||||
struct Color color;
|
||||
glm::mat4 model;
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
bool hasTexture;
|
||||
};
|
||||
|
||||
class SimpleTexturedMaterial : public Material {
|
||||
private:
|
||||
struct SimpleTexturedShaderData data;
|
||||
struct SimpleTexturedMaterialShaderData data;
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
protected:
|
||||
std::vector<std::shared_ptr<IShaderBase>> getLockedShaders(
|
||||
ShaderManager &shaderManager
|
||||
) override;
|
||||
|
||||
public:
|
||||
void load(std::shared_ptr<SceneLoadContext> ctx) override;
|
||||
@@ -48,7 +53,7 @@ namespace Dawn {
|
||||
*/
|
||||
void setColor(const struct Color color);
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> getPasses(
|
||||
std::vector<std::shared_ptr<RenderPass>> getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) override;
|
||||
};
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
UICanvas.cpp
|
||||
)
|
||||
@@ -1,144 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UICanvas.hpp"
|
||||
#include "display/pass/RenderPass.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "ui/UIElement.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UICanvas::onInit() {
|
||||
mesh = std::make_shared<Mesh>();
|
||||
mesh->createBuffers(
|
||||
QUAD_VERTICE_COUNT * UI_SHADER_QUAD_COUNT,
|
||||
QUAD_INDICE_COUNT * UI_SHADER_QUAD_COUNT
|
||||
);
|
||||
|
||||
for(int32_t i = 0; i < UI_SHADER_QUAD_COUNT; i++) {
|
||||
QuadMesh::bufferWithIndex(
|
||||
mesh,
|
||||
glm::vec4(0, 0, 1, 1),
|
||||
glm::vec4(0, 0, 1, 1),
|
||||
i * QUAD_VERTICE_COUNT,
|
||||
i * QUAD_INDICE_COUNT,
|
||||
i * QUAD_VERTICE_COUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void UICanvas::onDispose() {
|
||||
mesh = nullptr;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> UICanvas::getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) {
|
||||
if(this->elements.empty()) return {};
|
||||
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
|
||||
// Setup the projection and views
|
||||
data.projection = glm::ortho(
|
||||
0.0f, ctx.renderTarget->getWidth(),
|
||||
ctx.renderTarget->getHeight(), 0.0f,
|
||||
0.0f, 1.0f
|
||||
);
|
||||
data.view = glm::mat4(1.0f);
|
||||
data.model = glm::mat4(1.0f);
|
||||
|
||||
// Reset the passes
|
||||
this->passes.clear();
|
||||
this->textureBindings.clear();
|
||||
this->textures.clear();
|
||||
quadCount = 0;
|
||||
nextBinding = 0;
|
||||
|
||||
// Alignment root
|
||||
const glm::vec2 rootPosition = { 0, 0 };
|
||||
const glm::vec2 rootSize = {
|
||||
ctx.renderTarget->getWidth(),
|
||||
ctx.renderTarget->getHeight()
|
||||
};
|
||||
const float_t rootScale = 1.0f;
|
||||
|
||||
// Get the quads for each component
|
||||
auto itComponents = elements.begin();
|
||||
auto self = std::ref(*this);
|
||||
while(itComponents != elements.end()) {
|
||||
auto component = *itComponents;
|
||||
component->updateAlignment(rootPosition, rootSize, rootScale);
|
||||
component->getQuads(self);
|
||||
++itComponents;
|
||||
}
|
||||
|
||||
// Flush the remaining quads
|
||||
flushPass();
|
||||
return passes;
|
||||
}
|
||||
|
||||
void UICanvas::addQuad(
|
||||
const glm::vec4 quad,
|
||||
const glm::vec4 uvs,
|
||||
const struct Color color,
|
||||
const enum UIShaderQuadStyle style,
|
||||
const std::shared_ptr<Texture> text
|
||||
) {
|
||||
glm::vec4 styleData;
|
||||
styleData[0] = (float_t)style;
|
||||
|
||||
if(text == nullptr) {
|
||||
styleData[1] = -1;
|
||||
} else {
|
||||
shadertexturebinding_t texture;
|
||||
auto bindingIt = textureBindings.find(text);
|
||||
if(bindingIt == textureBindings.end()) {
|
||||
if(nextBinding >= UI_SHADER_TEXTURE_COUNT) {
|
||||
flushPass();
|
||||
}
|
||||
textureBindings[text] = nextBinding;
|
||||
textures[nextBinding] = text;
|
||||
data.textures[nextBinding] = nextBinding;
|
||||
texture = nextBinding++;
|
||||
} else {
|
||||
texture = bindingIt->second;
|
||||
}
|
||||
styleData[1] = (float_t)texture;
|
||||
}
|
||||
|
||||
data.quads[quadCount] = {
|
||||
quad,
|
||||
uvs,
|
||||
color,
|
||||
styleData
|
||||
};
|
||||
quadCount++;
|
||||
if(quadCount == UI_SHADER_QUAD_COUNT) flushPass();
|
||||
}
|
||||
|
||||
void UICanvas::flushPass() {
|
||||
if(quadCount == 0) return;
|
||||
|
||||
auto pass = createRenderPass<UIShader, UIShaderData>(
|
||||
std::ref(*this),
|
||||
data,
|
||||
textures,
|
||||
mesh,
|
||||
MeshDrawMode::TRIANGLES,
|
||||
0,
|
||||
quadCount * QUAD_INDICE_COUNT
|
||||
);
|
||||
passes.push_back(pass);
|
||||
|
||||
quadCount = 0;
|
||||
nextBinding = 0;
|
||||
textures.clear();
|
||||
textureBindings.clear();
|
||||
}
|
||||
|
||||
void UICanvas::addElement(const std::shared_ptr<UIElement> element) {
|
||||
elements.push_back(element);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItem.hpp"
|
||||
#include "component/display/IRenderableComponent.hpp"
|
||||
#include "display/shader/UIShader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIElement;
|
||||
|
||||
class UICanvas :
|
||||
public SceneComponent,
|
||||
public IRenderableComponent
|
||||
{
|
||||
private:
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
UIShaderData data;
|
||||
std::vector<std::shared_ptr<UIElement>> elements;
|
||||
|
||||
size_t quadCount = 0;
|
||||
shadertexturebinding_t nextBinding = 0;
|
||||
std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures;
|
||||
std::map<
|
||||
std::shared_ptr<Texture>, shadertexturebinding_t
|
||||
> textureBindings;
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> passes;
|
||||
|
||||
protected:
|
||||
virtual void onInit() override;
|
||||
virtual void onDispose() override;
|
||||
|
||||
/**
|
||||
* Flushes all pending quads to the render pass. This doesn't actually
|
||||
* render anything, it just flushes the data buffer to a new pass.
|
||||
*/
|
||||
void flushPass();
|
||||
|
||||
public:
|
||||
std::vector<std::shared_ptr<IRenderPass>> getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) override;
|
||||
|
||||
/**
|
||||
* Adds a quad to the canvas and performs a flush if necessary.
|
||||
*
|
||||
* @param quad The quad to add.
|
||||
* @param uvs The UVs to use for the quad.
|
||||
* @param color The color to use for the quad.
|
||||
* @param style Style that the quad should be rendered in.
|
||||
* @param texture The texture to use for the quad, can be null.
|
||||
*/
|
||||
void addQuad(
|
||||
const glm::vec4 quad,
|
||||
const glm::vec4 uvs,
|
||||
const struct Color color,
|
||||
const enum UIShaderQuadStyle style,
|
||||
const std::shared_ptr<Texture> texture = nullptr
|
||||
);
|
||||
|
||||
/**
|
||||
* Adds a component to the canvas.
|
||||
*
|
||||
* @param component The component to add.
|
||||
*/
|
||||
void addElement(const std::shared_ptr<UIElement> component);
|
||||
};
|
||||
}
|
||||
@@ -15,4 +15,5 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
add_subdirectory(mesh)
|
||||
add_subdirectory(shader)
|
||||
add_subdirectory(font)
|
||||
add_subdirectory(tileset)
|
||||
add_subdirectory(tileset)
|
||||
add_subdirectory(pass)
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "dawn.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
#include "display/RenderPipeline.hpp"
|
||||
#include "display/shader/ShaderManager.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Game;
|
||||
@@ -15,7 +14,6 @@ namespace Dawn {
|
||||
class IRenderHost {
|
||||
public:
|
||||
RenderPipeline renderPipeline;
|
||||
ShaderManager shaderManager;
|
||||
|
||||
/**
|
||||
* Creates a render host.
|
||||
|
||||
@@ -78,7 +78,7 @@ void RenderPipeline::renderSceneCamera(
|
||||
};
|
||||
|
||||
// Get list of renderables
|
||||
std::vector<std::shared_ptr<IRenderPass>> renderPasses;
|
||||
std::vector<std::shared_ptr<RenderPass>> renderPasses;
|
||||
auto renderables = scene->findComponents<IRenderableComponent>();
|
||||
for(auto renderable : renderables) {
|
||||
auto rp = renderable->getPasses(ctx);
|
||||
@@ -95,9 +95,6 @@ void RenderPipeline::renderSceneCamera(
|
||||
);
|
||||
|
||||
for(auto renderPass : renderPasses) {
|
||||
renderPass->bind();
|
||||
renderPass->setData();
|
||||
renderPass->upload();
|
||||
renderPass->draw();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
MapShader.cpp
|
||||
RenderPass.cpp
|
||||
)
|
||||
@@ -1,40 +0,0 @@
|
||||
// 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"
|
||||
|
||||
namespace Dawn {
|
||||
class IRenderPass {
|
||||
public:
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
|
||||
/**
|
||||
* Binds the shader for this render pass.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Sets the data for this render pass to the shader.
|
||||
*/
|
||||
virtual void setData() = 0;
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
virtual void upload() = 0;
|
||||
|
||||
/**
|
||||
* Draws the mesh for this render pass.
|
||||
*/
|
||||
virtual void draw() = 0;
|
||||
|
||||
/**
|
||||
* Cleans up the render pass.
|
||||
*/
|
||||
virtual ~IRenderPass() {
|
||||
}
|
||||
};
|
||||
}
|
||||
32
src/dawn/display/pass/RenderPass.cpp
Normal file
32
src/dawn/display/pass/RenderPass.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RenderPass.hpp"
|
||||
#include "component/display/MeshRenderer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPass::RenderPass(
|
||||
SceneComponent &self,
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t indiceStart,
|
||||
const int32_t indiceCount
|
||||
) :
|
||||
mesh(mesh),
|
||||
drawMode(drawMode),
|
||||
indiceStart(indiceStart),
|
||||
indiceCount(indiceCount)
|
||||
{
|
||||
// Need mesh?
|
||||
if(!this->mesh) {
|
||||
auto meshRenderer = self.getItem()->getComponent<MeshRenderer>();
|
||||
if(meshRenderer) this->mesh = meshRenderer->mesh;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPass::draw() {
|
||||
mesh->draw(drawMode, indiceStart, indiceCount);
|
||||
}
|
||||
@@ -4,25 +4,16 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "game/Game.hpp"
|
||||
#include "display/pass/IRenderPass.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "component/display/MeshRenderer.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
#include "scene/SceneComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<class S, typename D>
|
||||
class RenderPass : public IRenderPass {
|
||||
class RenderPass {
|
||||
private:
|
||||
std::shared_ptr<S> shader;
|
||||
const std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures;
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
const enum MeshDrawMode drawMode;
|
||||
const int32_t indiceStart;
|
||||
const int32_t indiceCount;
|
||||
const D data;
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -37,58 +28,20 @@ namespace Dawn {
|
||||
*/
|
||||
RenderPass(
|
||||
SceneComponent &self,
|
||||
const D d,
|
||||
const std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures,
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t indiceStart,
|
||||
const int32_t indiceCount
|
||||
) :
|
||||
data(d),
|
||||
textures(textures),
|
||||
mesh(mesh),
|
||||
drawMode(drawMode),
|
||||
indiceStart(indiceStart),
|
||||
indiceCount(indiceCount)
|
||||
{
|
||||
//Get the shader
|
||||
shader = (
|
||||
self.getGame()->renderHost->shaderManager.getShader<S>()
|
||||
);
|
||||
assertNotNull(shader, "Shader cannot be null!");
|
||||
);
|
||||
|
||||
// Need mesh?
|
||||
if(!this->mesh) {
|
||||
auto meshRenderer = self.getItem()->getComponent<MeshRenderer>();
|
||||
if(meshRenderer) this->mesh = meshRenderer->mesh;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Draws the mesh for this render pass.
|
||||
*/
|
||||
void draw();
|
||||
|
||||
void bind() override {
|
||||
shader->bind();
|
||||
}
|
||||
|
||||
void setData() override {
|
||||
shader->setData(data);
|
||||
}
|
||||
|
||||
void upload() override {
|
||||
for(auto &pair : textures) {
|
||||
if(!pair.second->isReady()) continue;
|
||||
pair.second->bind(pair.first);
|
||||
}
|
||||
shader->upload();
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
if(mesh) {
|
||||
mesh->draw(drawMode, indiceStart, indiceCount);
|
||||
}
|
||||
}
|
||||
|
||||
~RenderPass() override {
|
||||
}
|
||||
/**
|
||||
* Cleans up the render pass.
|
||||
*/
|
||||
~RenderPass();
|
||||
};
|
||||
}
|
||||
@@ -6,9 +6,9 @@
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
IShader.cpp
|
||||
IShaderProgram.cpp
|
||||
IShaderStage.cpp
|
||||
ShaderManager.cpp
|
||||
ShaderManagerSlangFileSystem.cpp
|
||||
IShaderProgram2.cpp
|
||||
IShaderProgram.cpp
|
||||
)
|
||||
@@ -1,46 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
size_t shaderParameterTypeGetSize(const ShaderParameterType type) {
|
||||
switch(type) {
|
||||
case ShaderParameterType::VEC2:
|
||||
return sizeof(glm::vec2);
|
||||
|
||||
case ShaderParameterType::VEC3:
|
||||
return sizeof(glm::vec3);
|
||||
|
||||
case ShaderParameterType::VEC4:
|
||||
return sizeof(glm::vec4);
|
||||
|
||||
case ShaderParameterType::MAT3:
|
||||
return sizeof(glm::mat3);
|
||||
|
||||
case ShaderParameterType::MAT4:
|
||||
return sizeof(glm::mat4);
|
||||
|
||||
case ShaderParameterType::COLOR:
|
||||
return sizeof(struct Color);
|
||||
|
||||
case ShaderParameterType::FLOAT:
|
||||
return sizeof(float);
|
||||
|
||||
case ShaderParameterType::INT:
|
||||
return sizeof(int32_t);
|
||||
|
||||
case ShaderParameterType::TEXTURE:
|
||||
return sizeof(shadertexturebinding_t);
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown ShaderParameterType");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderParameterType {
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
MAT3,
|
||||
MAT4,
|
||||
COLOR,
|
||||
FLOAT,
|
||||
INT,
|
||||
TEXTURE,
|
||||
BOOLEAN
|
||||
};
|
||||
|
||||
class IShaderBase {
|
||||
public:
|
||||
virtual ~IShaderBase() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class IShader : public IShaderBase {
|
||||
protected:
|
||||
T data;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the currently uploaded data on the Shader.
|
||||
*
|
||||
* @return The uploaded data.
|
||||
*/
|
||||
T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entire data to be uploaded.
|
||||
*
|
||||
* @param data Data to be uploaded.
|
||||
*/
|
||||
void setData(const T data) {
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the shader, this needs to be called before the shader can
|
||||
* be used.
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Binds the shader as the current one, does not upload any data, somewhat
|
||||
* relies on something else uploading the data.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
virtual void upload() = 0;
|
||||
|
||||
/**
|
||||
* Disposes of the shader.
|
||||
*/
|
||||
virtual ~IShader() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the ShaderParameterType.
|
||||
*
|
||||
* @param type The type to get the size of.
|
||||
* @return Size of the type.
|
||||
*/
|
||||
size_t shaderParameterTypeGetSize(const Dawn::ShaderParameterType type);
|
||||
17
src/dawn/display/shader/IShaderProgram.cpp
Normal file
17
src/dawn/display/shader/IShaderProgram.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "IShaderProgram.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void IShaderProgram::init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) {
|
||||
this->stages = stages;
|
||||
}
|
||||
|
||||
IShaderProgram::~IShaderProgram() {
|
||||
}
|
||||
30
src/dawn/display/shader/IShaderProgram.hpp
Normal file
30
src/dawn/display/shader/IShaderProgram.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/ShaderStage.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
||||
class IShaderProgram {
|
||||
protected:
|
||||
std::vector<std::shared_ptr<ShaderStage>> stages;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize the IShaderProgram2 object
|
||||
*
|
||||
* @param stages The list of shader stages to initialize with.
|
||||
*/
|
||||
virtual void init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Destroy the IShaderProgram2 object
|
||||
*/
|
||||
virtual ~IShaderProgram();
|
||||
};
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "IShaderProgram2.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
IShaderEntry::~IShaderEntry() {
|
||||
}
|
||||
|
||||
void IShaderProgram2::init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) {
|
||||
this->entries = entries;
|
||||
}
|
||||
|
||||
IShaderProgram2::~IShaderProgram2() {
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "slang.h"
|
||||
|
||||
using namespace slang;
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderEntry;
|
||||
|
||||
class IShaderEntry {
|
||||
public:
|
||||
/**
|
||||
* Initialize the IShaderEntry object
|
||||
*
|
||||
* @param stage The stage of the shader entry.
|
||||
* @param code The code of the shader entry.
|
||||
*/
|
||||
virtual void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Destroy the IShaderEntry object
|
||||
*/
|
||||
virtual ~IShaderEntry();
|
||||
};
|
||||
|
||||
class IShaderProgram2 {
|
||||
protected:
|
||||
std::vector<std::shared_ptr<ShaderEntry>> entries;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initialize the IShaderProgram2 object
|
||||
*
|
||||
* @param entries The list of shader entries to initialize with.
|
||||
*/
|
||||
virtual void init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Destroy the IShaderProgram2 object
|
||||
*/
|
||||
virtual ~IShaderProgram2();
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
@@ -7,12 +7,5 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
IShaderStage::IShaderStage(const ShaderStageType type) :
|
||||
type(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IShaderStage::~IShaderStage() {
|
||||
|
||||
}
|
||||
@@ -1,31 +1,30 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "slang.h"
|
||||
|
||||
using namespace slang;
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderStageType {
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
// COMPUTE
|
||||
};
|
||||
|
||||
class IShaderStage {
|
||||
public:
|
||||
const enum ShaderStageType type;
|
||||
|
||||
/**
|
||||
* Constructs a new Shader Stage.
|
||||
* Initialize the IShaderEntry object
|
||||
*
|
||||
* @param type Type of shader stage.
|
||||
* @param stage The stage of the shader entry.
|
||||
* @param code The code of the shader entry.
|
||||
*/
|
||||
IShaderStage(const ShaderStageType type);
|
||||
virtual void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Destroy the IShaderStage object
|
||||
* Destroy the IShaderEntry object
|
||||
*/
|
||||
virtual ~IShaderStage();
|
||||
};
|
||||
|
||||
@@ -47,6 +47,4 @@ std::shared_ptr<Game> ShaderManager::getGame() {
|
||||
}
|
||||
|
||||
ShaderManager::~ShaderManager() {
|
||||
// Clear all shaders
|
||||
shaders.clear();
|
||||
}
|
||||
@@ -4,7 +4,6 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "ShaderManagerSlangFileSystem.hpp"
|
||||
using namespace slang;
|
||||
|
||||
@@ -14,11 +13,8 @@ namespace Dawn {
|
||||
|
||||
class ShaderManager : public std::enable_shared_from_this<ShaderManager> {
|
||||
private:
|
||||
std::vector<std::weak_ptr<IShaderBase>> shaders;
|
||||
|
||||
std::weak_ptr<Game> game;
|
||||
ShaderManagerSlangFileSystem fileSystem;
|
||||
|
||||
Slang::ComPtr<IGlobalSession> globalSession;
|
||||
TargetDesc targetDescription;
|
||||
SessionDesc sessionDescription;
|
||||
@@ -44,34 +40,6 @@ namespace Dawn {
|
||||
*/
|
||||
std::shared_ptr<Game> getGame();
|
||||
|
||||
/**
|
||||
* Retreives an instance of the shader from the shader manager. If the
|
||||
* shader does not exist it will be created.
|
||||
*
|
||||
* @tparam T Type of shader to retreive.
|
||||
* @return Shader instance.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getShader() {
|
||||
auto itShaders = shaders.begin();
|
||||
while(itShaders != shaders.end()) {
|
||||
auto shader = itShaders->lock();
|
||||
if(!shader) {
|
||||
itShaders = shaders.erase(itShaders);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
|
||||
if(casted) return casted;
|
||||
itShaders++;
|
||||
}
|
||||
|
||||
auto newShader = std::make_shared<T>();
|
||||
shaders.push_back(newShader);
|
||||
newShader->init();
|
||||
return newShader;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of all shaders.
|
||||
*/
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
UIAlignableElement.cpp
|
||||
UISubAlignableElement.cpp
|
||||
UIElement.cpp
|
||||
UIMenu.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(container)
|
||||
add_subdirectory(elements)
|
||||
@@ -1,247 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIAlignableElement.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIAlignableElement::UIAlignableElement() {
|
||||
alignUnit[0] = UIAlignmentUnit::SCALE;
|
||||
alignUnit[1] = UIAlignmentUnit::SCALE;
|
||||
alignUnit[2] = UIAlignmentUnit::SCALE;
|
||||
alignUnit[3] = UIAlignmentUnit::SCALE;
|
||||
|
||||
eventAlignmentUpdated = [&](const glm::vec2 p, const glm::vec2 s) {
|
||||
};
|
||||
}
|
||||
|
||||
void UIAlignableElement::updateSelfAlignment(
|
||||
const glm::vec2 pPos,
|
||||
const glm::vec2 pSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
auto valueAxis = [&](
|
||||
const enum UIAlignmentUnit unit,
|
||||
const float_t alignment,
|
||||
const float_t parentSize,
|
||||
const float_t ratioSize,
|
||||
const float_t contentSize
|
||||
) {
|
||||
if(alignment == UI_ALIGN_SIZE_AUTO) return contentSize;
|
||||
|
||||
switch(unit) {
|
||||
case UIAlignmentUnit::PIXEL:
|
||||
return alignment;
|
||||
|
||||
case UIAlignmentUnit::SCALE:
|
||||
return canvasScale * alignment;
|
||||
|
||||
case UIAlignmentUnit::PERCENT:
|
||||
return parentSize * (alignment / 100.0f);
|
||||
|
||||
case UIAlignmentUnit::RATIO:
|
||||
return (alignment / 100.0f) * ratioSize;
|
||||
|
||||
default:
|
||||
assertUnreachable("Invalid UIAlignmentType");
|
||||
return 0.0f;
|
||||
}
|
||||
};
|
||||
|
||||
auto alignAxis = [&](
|
||||
const enum UIAlignmentType type,
|
||||
const enum UIAlignmentUnit unit0,
|
||||
const enum UIAlignmentUnit unit1,
|
||||
const float_t alignment0,
|
||||
const float_t alignment1,
|
||||
const float_t parentSize,
|
||||
const float_t ratioSize,
|
||||
const float_t contentSize,
|
||||
float_t &outPosition,
|
||||
float_t &outSize
|
||||
) {
|
||||
switch(type) {
|
||||
case UIAlignmentType::START:
|
||||
outPosition = valueAxis(
|
||||
unit0,
|
||||
alignment0,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
outSize = valueAxis(
|
||||
unit1,
|
||||
alignment1,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
break;
|
||||
|
||||
case UIAlignmentType::MIDDLE:
|
||||
outSize = valueAxis(
|
||||
unit1,
|
||||
alignment1,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
outPosition = (parentSize / 2.0f) - (contentSize / 2.0f) + valueAxis(
|
||||
unit0,
|
||||
alignment0,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
break;
|
||||
|
||||
case UIAlignmentType::END:
|
||||
outSize = valueAxis(
|
||||
unit0,
|
||||
alignment0,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
outPosition = parentSize - outSize - valueAxis(
|
||||
unit1,
|
||||
alignment1,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
break;
|
||||
|
||||
case UIAlignmentType::STRETCH:
|
||||
outPosition = valueAxis(
|
||||
unit0,
|
||||
alignment0,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
);
|
||||
outSize = parentSize - (outPosition + valueAxis(
|
||||
unit1,
|
||||
alignment1,
|
||||
parentSize,
|
||||
ratioSize,
|
||||
contentSize
|
||||
));
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Invalid UIAlignmentType");
|
||||
}
|
||||
};
|
||||
|
||||
bool_t heightFirst = (
|
||||
alignUnit[0] == UIAlignmentUnit::RATIO ||
|
||||
alignUnit[2] == UIAlignmentUnit::RATIO
|
||||
);
|
||||
|
||||
if(heightFirst) {
|
||||
// Align height first, this will define size.y which we can use as the ratio
|
||||
// for the width/X axis alignment.
|
||||
alignAxis(
|
||||
alignY,
|
||||
alignUnit[1],
|
||||
alignUnit[3],
|
||||
align[1],
|
||||
align[3],
|
||||
pSize.y,
|
||||
0,
|
||||
this->getContentHeight(),
|
||||
position.y,
|
||||
size.y
|
||||
);
|
||||
alignAxis(
|
||||
alignX,
|
||||
alignUnit[0],
|
||||
alignUnit[2],
|
||||
align[0],
|
||||
align[2],
|
||||
pSize.x,
|
||||
size.y,
|
||||
this->getContentWidth(),
|
||||
position.x,
|
||||
size.x
|
||||
);
|
||||
} else {
|
||||
alignAxis(
|
||||
alignX,
|
||||
alignUnit[0],
|
||||
alignUnit[2],
|
||||
align[0],
|
||||
align[2],
|
||||
pSize.x,
|
||||
0,
|
||||
this->getContentWidth(),
|
||||
position.x,
|
||||
size.x
|
||||
);
|
||||
alignAxis(
|
||||
alignY,
|
||||
alignUnit[1],
|
||||
alignUnit[3],
|
||||
align[1],
|
||||
align[3],
|
||||
pSize.y,
|
||||
size.x,
|
||||
this->getContentHeight(),
|
||||
position.y,
|
||||
size.y
|
||||
);
|
||||
}
|
||||
|
||||
this->position += pPos;
|
||||
this->eventAlignmentUpdated(position, size);
|
||||
}
|
||||
|
||||
bool_t UIAlignableElement::hasExplicitWidth() {
|
||||
if(size.x == 0.0f) return false;
|
||||
if(
|
||||
(alignX == UIAlignmentType::STRETCH) ||
|
||||
(alignX == UIAlignmentType::END)
|
||||
) {
|
||||
return align[0] != UI_ALIGN_SIZE_AUTO;
|
||||
}
|
||||
return align[2] != UI_ALIGN_SIZE_AUTO;
|
||||
}
|
||||
|
||||
bool_t UIAlignableElement::hasExplicitHeight() {
|
||||
if(size.y == 0.0f) return false;
|
||||
if(
|
||||
(alignY == UIAlignmentType::STRETCH) ||
|
||||
(alignY == UIAlignmentType::END)
|
||||
) {
|
||||
return align[1] != UI_ALIGN_SIZE_AUTO;
|
||||
}
|
||||
return align[3] != UI_ALIGN_SIZE_AUTO;
|
||||
}
|
||||
|
||||
float_t UIAlignableElement::getWidth() {
|
||||
if(hasExplicitWidth()) return size.x;
|
||||
return getContentWidth();
|
||||
}
|
||||
|
||||
float_t UIAlignableElement::getHeight() {
|
||||
if(hasExplicitHeight()) return size.y;
|
||||
return getContentHeight();
|
||||
}
|
||||
|
||||
|
||||
void UIAlignableElement::updateAlignment(
|
||||
const glm::vec2 pPos,
|
||||
const glm::vec2 pSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
this->updateSelfAlignment(pPos, pSize, canvasScale);
|
||||
|
||||
// Now update children alignment
|
||||
auto children = getChildren();
|
||||
for(auto &c : children) {
|
||||
c->updateAlignment(this->position, this->size, canvasScale);
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UIElement.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
#define UI_ALIGN_SIZE_AUTO -1.0f
|
||||
|
||||
enum class UIAlignmentType {
|
||||
START,
|
||||
MIDDLE,
|
||||
END,
|
||||
STRETCH
|
||||
};
|
||||
|
||||
enum class UIAlignmentUnit {
|
||||
PIXEL,
|
||||
SCALE,
|
||||
PERCENT,
|
||||
RATIO
|
||||
};
|
||||
|
||||
class UIAlignableElement : public UIElement {
|
||||
protected:
|
||||
glm::vec2 position;
|
||||
glm::vec2 size;
|
||||
|
||||
/**
|
||||
* Updates the alignment of this element ONLY.
|
||||
*
|
||||
* @param parentPosition The position of the parent.
|
||||
* @param parentSize The size of the parent.
|
||||
* @param canvasScale The scale of the canvas.
|
||||
*/
|
||||
virtual void updateSelfAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns true only if the width of this component is explicitly set.
|
||||
*
|
||||
* @return True if the width of this component is explicitly set.
|
||||
*/
|
||||
bool_t hasExplicitWidth();
|
||||
|
||||
/**
|
||||
* Returns true only if the height of this component is explicitly set.
|
||||
*
|
||||
* @return True if the height of this component is explicitly set.
|
||||
*/
|
||||
bool_t hasExplicitHeight();
|
||||
|
||||
public:
|
||||
// Primary alignment controls
|
||||
glm::vec4 align = glm::vec4(0, 0, 0, 0);
|
||||
enum UIAlignmentType alignX = UIAlignmentType::STRETCH;
|
||||
enum UIAlignmentType alignY = UIAlignmentType::STRETCH;
|
||||
enum UIAlignmentUnit alignUnit[4];
|
||||
|
||||
std::function<
|
||||
void(const glm::vec2, const glm::vec2)
|
||||
> eventAlignmentUpdated;
|
||||
|
||||
/**
|
||||
* Constructor for the UIAlignableElement.
|
||||
*/
|
||||
UIAlignableElement();
|
||||
|
||||
float_t getWidth() override;
|
||||
float_t getHeight() override;
|
||||
|
||||
void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIElement.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::shared_ptr<UIElement>> UIElement::getChildren() {
|
||||
return {};
|
||||
}
|
||||
|
||||
void UIElement::getSelfQuads(UICanvas &ctx) {
|
||||
//Do nothing
|
||||
}
|
||||
|
||||
float_t UIElement::getContentWidth() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float_t UIElement::getContentHeight() {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
float_t UIElement::getWidth() {
|
||||
return this->getContentWidth();
|
||||
}
|
||||
|
||||
float_t UIElement::getHeight() {
|
||||
return this->getContentHeight();
|
||||
}
|
||||
|
||||
void UIElement::getQuads(UICanvas &ctx) {
|
||||
this->getSelfQuads(ctx);
|
||||
|
||||
auto children = getChildren();
|
||||
for(auto &c : children) {
|
||||
c->getQuads(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
void UIElement::updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
auto children = getChildren();
|
||||
for(auto &c : children) {
|
||||
c->updateAlignment(parentPosition, parentSize, canvasScale);
|
||||
}
|
||||
}
|
||||
@@ -1,80 +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/UIShader.hpp"
|
||||
#include "component/ui/UICanvas.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIElement {
|
||||
protected:
|
||||
/**
|
||||
* Virtual method overridden by the UIElement to get the quads for the
|
||||
* component.
|
||||
*
|
||||
* @param alignment The alignment of this component.
|
||||
* @param ctx The canvas to add the quads to.
|
||||
*/
|
||||
virtual void getSelfQuads(UICanvas &ctx);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Overrided method by the UI Element that requests the minimum
|
||||
* width of the content.
|
||||
*
|
||||
* @return The minimum width of the content.
|
||||
*/
|
||||
virtual float_t getContentWidth();
|
||||
|
||||
/**
|
||||
* Overrided method by the UI Element that requests the minimum
|
||||
* height of the content.
|
||||
*
|
||||
* @return The minimum height of the content.
|
||||
*/
|
||||
virtual float_t getContentHeight();
|
||||
|
||||
/**
|
||||
* Returns the width of this component.
|
||||
*
|
||||
* @return The width of this component.
|
||||
*/
|
||||
virtual float_t getWidth();
|
||||
|
||||
/**
|
||||
* Returns the height of this component.
|
||||
*
|
||||
* @return The height of this component.
|
||||
*/
|
||||
virtual float_t getHeight();
|
||||
|
||||
/**
|
||||
* Virtual method overridden by the UIElement to get the children of
|
||||
* this component.
|
||||
*/
|
||||
virtual std::vector<std::shared_ptr<UIElement>> getChildren();
|
||||
|
||||
/**
|
||||
* Method called by the UICanvas to get the quads for this component.
|
||||
*
|
||||
* @param ctx The canvas to add the quads to.
|
||||
*/
|
||||
void getQuads(UICanvas &ctx);
|
||||
|
||||
/**
|
||||
* Updates the alignment of this component based on the parent. Typically
|
||||
* left to the UIAlignableElement to implement, default implementation
|
||||
* does nothing but invoke children.
|
||||
*
|
||||
* @param parentPosition The position of the parent.
|
||||
* @param parentSize The size of the parent.
|
||||
*/
|
||||
virtual void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIMenu.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UIMenu::setPosition(int32_t x, int32_t y) {
|
||||
assertTrue(x >= 0, "X position must be greater than or equal to 0.");
|
||||
assertTrue(y >= 0, "Y position must be greater than or equal to 0.");
|
||||
assertTrue(x < columns, "X must be less than the number of columns.");
|
||||
assertTrue(y < rows, "Y must be less than the number of rows.");
|
||||
|
||||
if(this->x == x && this->y == y) return;
|
||||
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
|
||||
eventPositionChanged.emit(x, y);
|
||||
}
|
||||
|
||||
void UIMenu::setSize(int32_t columns, int32_t rows) {
|
||||
assertTrue(columns > 0, "Columns must be greater than 0.");
|
||||
assertTrue(rows > 0, "Rows must be greater than 0.");
|
||||
assertTrue(columns > x, "Columns must be greater than current x position.");
|
||||
assertTrue(rows > y, "Rows must be greater than current y position.");
|
||||
|
||||
if(this->columns == columns && this->rows == rows) return;
|
||||
|
||||
this->columns = columns;
|
||||
this->rows = rows;
|
||||
}
|
||||
|
||||
int32_t UIMenu::getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
int32_t UIMenu::getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
int32_t UIMenu::getColumns() {
|
||||
return columns;
|
||||
}
|
||||
|
||||
int32_t UIMenu::getRows() {
|
||||
return rows;
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UIElement.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIMenu final : public UIElement {
|
||||
private:
|
||||
int32_t x = 0;
|
||||
int32_t y = 0;
|
||||
int32_t columns = 1;
|
||||
int32_t rows = 1;
|
||||
|
||||
public:
|
||||
Event<int32_t, int32_t> eventPositionChanged;
|
||||
|
||||
/**
|
||||
* Sets the position of this menu.
|
||||
*
|
||||
* @param x The x position of this menu.
|
||||
* @param y The y position of this menu.
|
||||
*/
|
||||
void setPosition(int32_t x, int32_t y);
|
||||
|
||||
/**
|
||||
* Sets the size of this menu.
|
||||
*
|
||||
* @param columns The number of columns in this menu.
|
||||
* @param rows The number of rows in this menu.
|
||||
*/
|
||||
void setSize(int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Gets the x position of this menu.
|
||||
*
|
||||
* @return The x position of this menu.
|
||||
*/
|
||||
int32_t getX();
|
||||
|
||||
/**
|
||||
* Gets the y position of this menu.
|
||||
*
|
||||
* @return The y position of this menu.
|
||||
*/
|
||||
int32_t getY();
|
||||
|
||||
/**
|
||||
* Gets the number of columns in this menu.
|
||||
*
|
||||
* @return The number of columns in this menu.
|
||||
*/
|
||||
int32_t getColumns();
|
||||
|
||||
/**
|
||||
* Gets the number of rows in this menu.
|
||||
*
|
||||
* @return The number of rows in this menu.
|
||||
*/
|
||||
int32_t getRows();
|
||||
};
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UISubAlignableElement.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UISubAlignableElement::updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
UIAlignableElement::updateAlignment(parentPosition, parentSize, canvasScale);
|
||||
|
||||
switch(this->subAlignX) {
|
||||
case UISubAlignment::START:
|
||||
this->subAlignedPosition.x = this->position.x;
|
||||
break;
|
||||
|
||||
case UISubAlignment::MIDDLE:
|
||||
this->subAlignedPosition.x = (
|
||||
this->position.x +
|
||||
(this->size.x / 2.0f) -
|
||||
(this->getContentWidth() / 2.0f)
|
||||
);
|
||||
break;
|
||||
|
||||
case UISubAlignment::END:
|
||||
this->subAlignedPosition.x = (
|
||||
this->position.x +
|
||||
this->size.x -
|
||||
this->getContentWidth()
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown UISubAlignment!");
|
||||
}
|
||||
|
||||
switch(this->subAlignY) {
|
||||
case UISubAlignment::START:
|
||||
this->subAlignedPosition.y = this->position.y;
|
||||
break;
|
||||
|
||||
case UISubAlignment::MIDDLE:
|
||||
this->subAlignedPosition.y = (
|
||||
this->position.y +
|
||||
(this->size.y / 2.0f) -
|
||||
(this->getContentHeight() / 2.0f)
|
||||
);
|
||||
break;
|
||||
|
||||
case UISubAlignment::END:
|
||||
this->subAlignedPosition.y = (
|
||||
this->position.y +
|
||||
this->size.y -
|
||||
this->getContentHeight()
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown UISubAlignment!");
|
||||
}
|
||||
|
||||
this->eventSubAlignmentUpdated.emit(this->subAlignedPosition);
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UIAlignableElement.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class UISubAlignment {
|
||||
START,
|
||||
MIDDLE,
|
||||
END
|
||||
};
|
||||
|
||||
class UISubAlignableElement : public UIAlignableElement {
|
||||
protected:
|
||||
glm::vec2 subAlignedPosition;
|
||||
|
||||
public:
|
||||
Event<glm::vec2> eventSubAlignmentUpdated;
|
||||
|
||||
enum UISubAlignment subAlignX = UISubAlignment::START;
|
||||
enum UISubAlignment subAlignY = UISubAlignment::START;
|
||||
|
||||
void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
UIColumnContainer.cpp
|
||||
UIContainer.cpp
|
||||
UIPaddingContainer.cpp
|
||||
UIRowContainer.cpp
|
||||
)
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assert.hpp"
|
||||
#include "UIColumnContainer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UIColumnContainer::updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
this->updateSelfAlignment(parentPosition, parentSize, canvasScale);
|
||||
|
||||
// Now we have our dimensions, divide evenly
|
||||
auto children = this->getChildren();
|
||||
|
||||
float_t x = 0.0f;
|
||||
float_t xPiece = this->size.x / (float_t)children.size();
|
||||
|
||||
// Update all children
|
||||
for(auto &child : children) {
|
||||
child->updateAlignment(
|
||||
this->position + glm::vec2(x, 0),
|
||||
glm::vec2(
|
||||
xPiece,
|
||||
this->size.y
|
||||
),
|
||||
canvasScale
|
||||
);
|
||||
x += xPiece;
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/container/UIContainer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIColumnContainer final : public UIContainer {
|
||||
public:
|
||||
void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assert.hpp"
|
||||
#include "UIContainer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<std::shared_ptr<UIElement>> UIContainer::getChildren() {
|
||||
return this->children;
|
||||
}
|
||||
|
||||
float_t UIContainer::getContentWidth() {
|
||||
float_t width = 0;
|
||||
auto children = this->getChildren();
|
||||
for(auto child : children) {
|
||||
width = Math::max(width, child->getWidth());
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
float_t UIContainer::getContentHeight() {
|
||||
float_t height = 0;
|
||||
auto children = this->getChildren();
|
||||
for(auto child : children) {
|
||||
height = Math::max(height, child->getHeight());
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
void UIContainer::appendChild(std::shared_ptr<UIElement> child) {
|
||||
assertNotNull(child, "Cannot append a null child!");
|
||||
this->children.push_back(child);
|
||||
}
|
||||
|
||||
void UIContainer::removeChild(std::shared_ptr<UIElement> child) {
|
||||
assertNotNull(child, "Cannot remove a null child!");
|
||||
auto it = std::find(this->children.begin(), this->children.end(), child);
|
||||
if(it == this->children.end()) return;
|
||||
this->children.erase(it);
|
||||
}
|
||||
|
||||
void UIContainer::clearChildren() {
|
||||
this->children.clear();
|
||||
}
|
||||
@@ -1,39 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UIAlignableElement.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIContainer : public UIAlignableElement {
|
||||
private:
|
||||
std::vector<std::shared_ptr<UIElement>> children;
|
||||
|
||||
public:
|
||||
std::vector<std::shared_ptr<UIElement>> getChildren() override;
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
|
||||
/**
|
||||
* Appends a child to this container.
|
||||
*
|
||||
* @param child Child to append.
|
||||
*/
|
||||
void appendChild(std::shared_ptr<UIElement> child);
|
||||
|
||||
/**
|
||||
* Removes a child from this container.
|
||||
*
|
||||
* @param child Child to remove.
|
||||
*/
|
||||
void removeChild(std::shared_ptr<UIElement> child);
|
||||
|
||||
/**
|
||||
* Removes all children from this container.
|
||||
*/
|
||||
void clearChildren();
|
||||
};
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIPaddingContainer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
float_t UIPaddingContainer::getContentWidth() {
|
||||
float_t width = 0.0f;
|
||||
for(auto &child : getChildren()) {
|
||||
width = Math::max(width, child->getWidth());
|
||||
}
|
||||
return width + padding.x + padding.z;
|
||||
}
|
||||
|
||||
float_t UIPaddingContainer::getContentHeight() {
|
||||
float_t height = 0.0f;
|
||||
for(auto &child : getChildren()) {
|
||||
height = Math::max(height, child->getHeight());
|
||||
}
|
||||
return height + padding.y + padding.w;
|
||||
}
|
||||
|
||||
void UIPaddingContainer::updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
glm::vec2 childPosition = parentPosition + glm::vec2(padding.x, padding.y);
|
||||
glm::vec2 childSize = parentSize - glm::vec2(padding.x + padding.z, padding.y + padding.w);
|
||||
|
||||
auto children = getChildren();
|
||||
for(auto &child : children) {
|
||||
child->updateAlignment(childPosition, childSize, canvasScale);
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/container/UIContainer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIPaddingContainer final : public UIContainer {
|
||||
public:
|
||||
glm::vec4 padding = { 0, 0, 0, 0 };
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIRowContainer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
float_t UIRowContainer::getContentWidth() {
|
||||
float_t width = 0.0f;
|
||||
for(auto &child : this->getChildren()) {
|
||||
width = Math::max(width, child->getWidth());
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
float_t UIRowContainer::getContentHeight() {
|
||||
float_t height = 0.0f;
|
||||
for(auto &child : this->getChildren()) {
|
||||
height += child->getHeight();
|
||||
}
|
||||
return height;
|
||||
}
|
||||
|
||||
void UIRowContainer::updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) {
|
||||
this->updateSelfAlignment(parentPosition, parentSize, canvasScale);
|
||||
|
||||
// Now we have our dimensions, divide evenly
|
||||
auto children = this->getChildren();
|
||||
|
||||
float_t y = 0.0f;
|
||||
float_t yPiece = this->size.y / (float_t)children.size();
|
||||
|
||||
// Update all children
|
||||
for(auto &child : children) {
|
||||
child->updateAlignment(
|
||||
this->position + glm::vec2(0, y),
|
||||
glm::vec2(
|
||||
this->size.x,
|
||||
yPiece
|
||||
),
|
||||
canvasScale
|
||||
);
|
||||
y += yPiece;
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/container/UIContainer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIRowContainer final : public UIContainer {
|
||||
public:
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
void updateAlignment(
|
||||
const glm::vec2 parentPosition,
|
||||
const glm::vec2 parentSize,
|
||||
const float_t canvasScale
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
UILabel.cpp
|
||||
UIRectangle.cpp
|
||||
)
|
||||
@@ -1,175 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UILabel.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UILabel::getSelfQuads(UICanvas &ctx) {
|
||||
std::vector<struct UIShaderQuad> quads;
|
||||
if(this->texture == nullptr || this->text.empty()) return;
|
||||
|
||||
glm::vec4 quad;
|
||||
glm::vec2 pos = glm::vec2(0, this->texture->fontSize);
|
||||
bool_t lastCharWasSpace = false;
|
||||
|
||||
for(size_t i = 0; i < text.size(); i++) {
|
||||
wchar_t c = text[i];
|
||||
auto info = texture->getCharacterData(c);
|
||||
|
||||
// Newline(s)
|
||||
if(c == L'\n') {
|
||||
pos.x = 0;
|
||||
pos.y += this->texture->fontSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Spaces
|
||||
if(c == L' ') {
|
||||
pos.x += info.advance.x;
|
||||
lastCharWasSpace = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Word Wrap
|
||||
if(wordWrap) {
|
||||
if(lastCharWasSpace) {
|
||||
// Scan ahead to next space
|
||||
float_t wordWidth = pos.x;// Start at current position and scan ahead.
|
||||
for(size_t j = i; j < text.size(); j++) {
|
||||
wchar_t c2 = text[j];
|
||||
if(c2 == L' ' || c2 == L'\n') {
|
||||
break;// If we hit another space, we are OK.
|
||||
}
|
||||
|
||||
// Will this character fit on the row? If not the whole word will wrap.
|
||||
auto info2 = texture->getCharacterData(c);
|
||||
wordWidth += info.advance.x;
|
||||
if(wordWidth > size.x) {
|
||||
pos.x = 0;
|
||||
pos.y += this->texture->fontSize;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastCharWasSpace = false;
|
||||
}
|
||||
// } else if(pos.x + info.size.x > subAlignedPosition.x + size.x) {
|
||||
// // Not word wrap, but instead just overflow characters.
|
||||
// pos.x = 0;
|
||||
// pos.y += this->texture->fontSize;
|
||||
}
|
||||
|
||||
ctx.addQuad(
|
||||
{
|
||||
subAlignedPosition.x + pos.x + info.offset.x,
|
||||
subAlignedPosition.y + pos.y + info.offset.y,
|
||||
subAlignedPosition.x + pos.x + info.size.x + info.offset.x,
|
||||
subAlignedPosition.y + pos.y + info.size.y + info.offset.y
|
||||
},
|
||||
{
|
||||
info.quad.x,
|
||||
info.quad.y,
|
||||
info.quad.z,
|
||||
info.quad.w
|
||||
},
|
||||
this->color,
|
||||
UIShaderQuadStyle::FONT,
|
||||
texture->texture
|
||||
);
|
||||
pos += info.advance;
|
||||
}
|
||||
}
|
||||
|
||||
float_t UILabel::getContentWidth() {
|
||||
if(this->texture == nullptr || this->text.empty()) return 0.0f;
|
||||
|
||||
float_t lineWidth = 0.0f;
|
||||
float_t width = 0.0f;
|
||||
for(wchar_t c : text) {
|
||||
if(c == L'\n') {
|
||||
width = Math::max<float_t>(width, lineWidth);
|
||||
lineWidth = 0.0f;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto info = texture->getCharacterData(c);
|
||||
lineWidth += info.advance.x;
|
||||
if(
|
||||
this->hasExplicitWidth() &&
|
||||
lineWidth >= size.x
|
||||
) return size.x;
|
||||
}
|
||||
width = Math::max<float_t>(width, lineWidth);
|
||||
return width;
|
||||
}
|
||||
|
||||
float_t UILabel::getContentHeight() {
|
||||
if(this->texture == nullptr || this->text.empty()) return 0.0f;
|
||||
|
||||
float_t height = this->texture->fontSize;
|
||||
float_t lineWidth = 0.0f;
|
||||
bool_t lastCharWasSpace = false;
|
||||
|
||||
for(wchar_t c : text) {
|
||||
if(c == L'\n') {
|
||||
height += this->texture->fontSize;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto info = texture->getCharacterData(c);
|
||||
|
||||
if(c == L' ') {
|
||||
lineWidth += info.advance.x;
|
||||
lastCharWasSpace = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(wordWrap) {
|
||||
if(lastCharWasSpace) {
|
||||
// Scan ahead to next space
|
||||
float_t wordWidth = lineWidth;// Start at current position and scan ahead.
|
||||
for(size_t j = 0; j < text.size(); j++) {
|
||||
wchar_t c2 = text[j];
|
||||
if(c2 == L' ' || c2 == L'\n') {
|
||||
break;// If we hit another space, we are OK.
|
||||
}
|
||||
|
||||
// Will this character fit on the row? If not the whole word will wrap.
|
||||
auto info2 = texture->getCharacterData(c);
|
||||
wordWidth += info.advance.x;
|
||||
if(wordWidth > size.x) {
|
||||
height += this->texture->fontSize;
|
||||
lineWidth = 0.0f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lastCharWasSpace = false;
|
||||
}
|
||||
// } else if(lineWidth + info.size.x > size.x) {
|
||||
// height += this->texture->fontSize;
|
||||
// lineWidth = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
std::shared_ptr<TrueTypeTexture> UILabel::getFont() {
|
||||
return this->texture;
|
||||
}
|
||||
|
||||
std::wstring UILabel::getText() {
|
||||
return this->text;
|
||||
}
|
||||
|
||||
void UILabel::setFont(std::shared_ptr<TrueTypeTexture> texture) {
|
||||
this->texture = texture;
|
||||
}
|
||||
|
||||
void UILabel::setText(const std::wstring &text) {
|
||||
this->text = text;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UISubAlignableElement.hpp"
|
||||
#include "display/font/TrueTypeTexture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UILabel final : public UISubAlignableElement {
|
||||
private:
|
||||
std::shared_ptr<TrueTypeTexture> texture = nullptr;
|
||||
std::wstring text = L"Hello World";
|
||||
|
||||
protected:
|
||||
void getSelfQuads(UICanvas &ctx) override;
|
||||
|
||||
public:
|
||||
bool_t wordWrap = true;
|
||||
struct Color color = COLOR_WHITE;
|
||||
|
||||
float_t getContentWidth() override;
|
||||
float_t getContentHeight() override;
|
||||
|
||||
/**
|
||||
* Returns the font used for this label.
|
||||
*
|
||||
* @return The font used for this label.
|
||||
*/
|
||||
std::shared_ptr<TrueTypeTexture> getFont();
|
||||
|
||||
/**
|
||||
* Returns the text used for this label.
|
||||
*
|
||||
* @return The text used for this label.
|
||||
*/
|
||||
std::wstring getText();
|
||||
|
||||
/**
|
||||
* Sets the font to use for this label.
|
||||
*
|
||||
* @param texture TrueType texture to use for this label.
|
||||
*/
|
||||
void setFont(std::shared_ptr<TrueTypeTexture> texture);
|
||||
|
||||
/**
|
||||
* Sets the text to use for this label.
|
||||
*
|
||||
* @param text The text to use for this label.
|
||||
*/
|
||||
void setText(const std::wstring &text);
|
||||
};
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UIRectangle.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UIRectangle::getSelfQuads(UICanvas &ctx) {
|
||||
std::vector<struct UIShaderQuad> quads;
|
||||
ctx.addQuad(
|
||||
glm::vec4(position, position + size),
|
||||
uv,
|
||||
color,
|
||||
UIShaderQuadStyle::TEXTURED,
|
||||
texture
|
||||
);
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "ui/UIAlignableElement.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class UIRectangle final : public UIAlignableElement {
|
||||
protected:
|
||||
void getSelfQuads(UICanvas &ctx) override;
|
||||
|
||||
public:
|
||||
struct Color color = COLOR_WHITE;
|
||||
std::shared_ptr<Texture> texture = nullptr;
|
||||
glm::vec4 uv = glm::vec4(0,0,1,1);
|
||||
};
|
||||
}
|
||||
@@ -6,10 +6,6 @@
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Shader.cpp
|
||||
ShaderProgram.cpp
|
||||
ShaderStage.cpp
|
||||
SimpleTexturedShader.cpp
|
||||
UIShader.cpp
|
||||
ShaderParameter.cpp
|
||||
ShaderProgram2.cpp
|
||||
)
|
||||
@@ -1,8 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Shader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
@@ -1,259 +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/ShaderStage.hpp"
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
#include "ShaderStructure.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef GLuint shadertexturebinding_t;
|
||||
|
||||
enum class ShaderOpenGLVariant {
|
||||
GLSL_330_CORE
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Shader : public IShader<T> {
|
||||
private:
|
||||
std::vector<std::shared_ptr<ShaderStage>> stages;
|
||||
std::vector<struct ShaderParameter> parameters;
|
||||
std::vector<struct IShaderStructure> structures;
|
||||
enum ShaderOpenGLVariant variant;
|
||||
|
||||
GLuint shaderProgram = -1;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Overridable function to get the stages for the shader.
|
||||
*
|
||||
* @param variant The variant of the shader to use.
|
||||
* @param rel The relative data to use.
|
||||
* @param stages The stages to add to.
|
||||
* @param parameters The parameters to add to.
|
||||
* @param structures The structures to add to.
|
||||
*/
|
||||
virtual void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const T *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes the shader, this needs to be called before the shader can
|
||||
* be used.
|
||||
*/
|
||||
void init() override {
|
||||
// Determine which kind of OpenGL shader to use.
|
||||
variant = ShaderOpenGLVariant::GLSL_330_CORE;
|
||||
|
||||
// Now get the stages
|
||||
T dummy;
|
||||
this->getStages(
|
||||
variant,
|
||||
&dummy,
|
||||
stages,
|
||||
parameters,
|
||||
structures
|
||||
);
|
||||
|
||||
// Create the shader program
|
||||
shaderProgram = glCreateProgram();
|
||||
assertNoGLError();
|
||||
|
||||
// Attach all the stages
|
||||
for(auto stage : stages) {
|
||||
glAttachShader(shaderProgram, stage->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Link and verify the program
|
||||
glLinkProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
|
||||
assertNoGLError();
|
||||
assertTrue(status == GL_TRUE, "Failed to link shader program.");
|
||||
|
||||
std::vector<std::string> uniformNames;
|
||||
GLint numUniforms = 0;
|
||||
|
||||
// Get the number of active uniforms
|
||||
glGetProgramiv(shaderProgram, GL_ACTIVE_UNIFORMS, &numUniforms);
|
||||
assertNoGLError();
|
||||
|
||||
// Iterate through each uniform
|
||||
// for (GLint i = 0; i < numUniforms; ++i) {
|
||||
// char name[256];
|
||||
// GLsizei length;
|
||||
// GLint size;
|
||||
// GLenum type;
|
||||
|
||||
// // Get the uniform name
|
||||
// glGetActiveUniform(shaderProgram, i, sizeof(name), &length, &size, &type, name);
|
||||
// assertNoGLError();
|
||||
// std::cout << "Uniform: " << i << ":" << name << std::endl;
|
||||
// // uniformNames.push_back(std::string(name));
|
||||
// }
|
||||
|
||||
// Map parameters correctly.
|
||||
std::for_each(
|
||||
parameters.begin(),
|
||||
parameters.end(),
|
||||
[&](struct ShaderParameter ¶m) {
|
||||
// Correct offset
|
||||
param.offset = param.offset - (size_t)(&dummy);
|
||||
param.location = glGetUniformLocation(
|
||||
shaderProgram,
|
||||
param.name.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
param.location != -1,
|
||||
"Failed to get location for parameter %s.",
|
||||
param.name.c_str()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Map structures
|
||||
std::for_each(
|
||||
structures.begin(),
|
||||
structures.end(),
|
||||
[&](struct IShaderStructure &structure) {
|
||||
structure.offset = structure.offset - (size_t)(&dummy);
|
||||
structure.location = glGetUniformBlockIndex(
|
||||
shaderProgram,
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
structure.location != -1,
|
||||
"Failed to get location for structure %s.",
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
|
||||
// Create the buffer
|
||||
glGenBuffers(1, &structure.buffer);
|
||||
}
|
||||
);
|
||||
|
||||
this->bind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the shader as the current one, does not upload any data, somewhat
|
||||
* relies on something else uploading the data.
|
||||
*/
|
||||
void bind() override {
|
||||
glUseProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
void upload() override {
|
||||
switch(this->variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
for(auto param : parameters) {
|
||||
void *value = (void*)(
|
||||
((size_t)&this->data) + param.offset
|
||||
);
|
||||
|
||||
switch(param.type) {
|
||||
case ShaderParameterType::MAT4: {
|
||||
glm::mat4 *matrix = (glm::mat4 *)value;
|
||||
if(param.count != 1) {
|
||||
assertUnreachable("I haven't implemented multiple mat4s");
|
||||
}
|
||||
glUniformMatrix4fv(
|
||||
param.location, 1, GL_FALSE, glm::value_ptr(*matrix)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::COLOR: {
|
||||
auto color = (Color *)value;
|
||||
glUniform4fv(
|
||||
param.location,
|
||||
param.count,
|
||||
(GLfloat*)value
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::BOOLEAN: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::TEXTURE: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unsupported ShaderParameterType");
|
||||
}
|
||||
}
|
||||
|
||||
assertNoGLError();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Upload structures
|
||||
for(auto structure : structures) {
|
||||
switch(structure.structureType) {
|
||||
case ShaderOpenGLStructureType::STD140: {
|
||||
// Upload the data
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, structure.location, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBufferData(
|
||||
GL_UNIFORM_BUFFER,
|
||||
structure.size * structure.count,
|
||||
(void*)((size_t)&this->data + (size_t)structure.offset),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
assertNoGLError();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLStructureType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Shader() {
|
||||
// Delete the structures
|
||||
for(auto structure : structures) {
|
||||
assertTrue(structure.buffer != -1, "Invalid buffer.");
|
||||
glDeleteBuffers(1, &structure.buffer);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Delete the shader program
|
||||
glDeleteProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderParameter::ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count
|
||||
) {
|
||||
this->name = name;
|
||||
this->offset = (size_t)offset;
|
||||
this->type = type;
|
||||
this->count = count;
|
||||
}
|
||||
@@ -1,33 +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/IShader.hpp"
|
||||
#include "dawnopengl.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ShaderParameter {
|
||||
std::string name;
|
||||
size_t offset;
|
||||
enum ShaderParameterType type;
|
||||
size_t count;
|
||||
GLint location = -1;
|
||||
|
||||
/**
|
||||
* Construct a new shader parameter.
|
||||
*
|
||||
* @param name Name of the parameter within the shader.
|
||||
* @param offset Offset, relative to the structure of the data.
|
||||
* @param type Type of the parameter.
|
||||
* @param count How many elements in the array (if multiple).
|
||||
*/
|
||||
ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count = 1
|
||||
);
|
||||
};
|
||||
}
|
||||
17
src/dawnopengl/display/shader/ShaderProgram.cpp
Normal file
17
src/dawnopengl/display/shader/ShaderProgram.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderProgram.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void ShaderProgram::init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) {
|
||||
IShaderProgram::init(stages);
|
||||
}
|
||||
|
||||
ShaderProgram::~ShaderProgram() {
|
||||
}
|
||||
17
src/dawnopengl/display/shader/ShaderProgram.hpp
Normal file
17
src/dawnopengl/display/shader/ShaderProgram.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShaderProgram.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderProgram : public IShaderProgram {
|
||||
public:
|
||||
void init(
|
||||
const std::vector<std::shared_ptr<ShaderStage>> &stages
|
||||
) override;
|
||||
~ShaderProgram();
|
||||
};
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderProgram2.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void ShaderEntry::init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) {
|
||||
}
|
||||
|
||||
ShaderEntry::~ShaderEntry() {
|
||||
}
|
||||
|
||||
// // //
|
||||
|
||||
void ShaderProgram2::init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) {
|
||||
IShaderProgram2::init(entries);
|
||||
}
|
||||
|
||||
ShaderProgram2::~ShaderProgram2() {
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShaderProgram2.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderEntry {
|
||||
protected:
|
||||
|
||||
public:
|
||||
void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
);
|
||||
~ShaderEntry();
|
||||
};
|
||||
|
||||
class ShaderProgram2 : public IShaderProgram2 {
|
||||
public:
|
||||
void init(
|
||||
const std::vector<std::shared_ptr<ShaderEntry>> &entries
|
||||
) override;
|
||||
~ShaderProgram2();
|
||||
};
|
||||
}
|
||||
@@ -1,74 +1,17 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assert/assertgl.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "ShaderStage.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderStage::ShaderStage(
|
||||
const enum ShaderStageType type,
|
||||
const std::string source
|
||||
) : IShaderStage(type) {
|
||||
// Get OpenGL Shader Type
|
||||
GLenum shaderType;
|
||||
switch(this->type) {
|
||||
case ShaderStageType::VERTEX:
|
||||
shaderType = GL_VERTEX_SHADER;
|
||||
break;
|
||||
|
||||
case ShaderStageType::FRAGMENT:
|
||||
shaderType = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
|
||||
// case ShaderStageType::COMPUTE:
|
||||
// shaderType = GL_COMPUTE;
|
||||
// break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown ShaderStageType");
|
||||
}
|
||||
|
||||
// Initialize the shader
|
||||
this->id = glCreateShader(shaderType);
|
||||
assertNoGLError();
|
||||
|
||||
// Compile the shader
|
||||
auto cSource = source.c_str();
|
||||
glShaderSource(this->id, 1, &cSource, NULL);
|
||||
assertNoGLError();
|
||||
glCompileShader(this->id);
|
||||
assertNoGLError();
|
||||
|
||||
// glShaderBinary(1, &this->id, GL_SHADER_BINARY_FORMAT_SPIR_V, source.data(), source.size());
|
||||
// assertNoGLError();
|
||||
// glSpecializeShader(this->id, "main", 0, NULL, NULL);
|
||||
// assertNoGLError();
|
||||
|
||||
// Validate
|
||||
GLint status;
|
||||
glGetShaderiv(this->id, GL_COMPILE_STATUS, &status);
|
||||
assertNoGLError();
|
||||
|
||||
if(!status) {
|
||||
// Failed to compile
|
||||
GLint logLength;
|
||||
glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &logLength);
|
||||
assertNoGLError();
|
||||
|
||||
GLchar *log = new GLchar[logLength];
|
||||
glGetShaderInfoLog(this->id, logLength, NULL, log);
|
||||
assertNoGLError();
|
||||
assertUnreachable("Failed to compile shader stage %i:\n%s", type, log);
|
||||
}
|
||||
void ShaderStage::init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) {
|
||||
}
|
||||
|
||||
ShaderStage::~ShaderStage() {
|
||||
if(this->id != -1) {
|
||||
glDeleteShader(this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
||||
@@ -1,28 +1,18 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/shader/IShaderStage.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderStage : public IShaderStage {
|
||||
public:
|
||||
GLuint id = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new ShaderStage.
|
||||
*
|
||||
* @param type The type of shader this is.
|
||||
* @param source The source code to compile.
|
||||
*/
|
||||
ShaderStage(const enum ShaderStageType type, const std::string source);
|
||||
|
||||
/**
|
||||
* Disposes of the shader stage.
|
||||
*/
|
||||
void init(
|
||||
const SlangStage &stage,
|
||||
const std::string &code
|
||||
) override;
|
||||
~ShaderStage();
|
||||
};
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma ocne
|
||||
#include "display/shader/ShaderParameter.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderOpenGLStructureType {
|
||||
STD140
|
||||
};
|
||||
|
||||
struct IShaderStructure {
|
||||
std::string structureName;
|
||||
size_t offset;
|
||||
enum ShaderOpenGLStructureType structureType;
|
||||
size_t size;
|
||||
size_t count;
|
||||
std::vector<struct ShaderParameter> parameters;
|
||||
GLint location = -1;
|
||||
GLuint buffer = -1;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ShaderStructure final : public IShaderStructure {
|
||||
public:
|
||||
/**
|
||||
* Constructs a new shader structure. Shader structures allow for larger
|
||||
* amounts/volumes of data to be passed to the shader in a single call.
|
||||
* Ideally I wouldn't really need this as I wanted the entire shader to
|
||||
* basically be a single large structure, but OpenGL doesn't support that
|
||||
* so I have to do this instead.
|
||||
*
|
||||
* @param structureName Structure name within the shader.
|
||||
* @param offset Offset, within the data structure, that this structure
|
||||
* starts at.
|
||||
* @param structureType The type of structure data format to use.
|
||||
* @param getParameters A callback that, when invoked, will populate the
|
||||
* parameters vector with the parameters for this
|
||||
* structure.
|
||||
* @param count The number of structures to create.
|
||||
*/
|
||||
ShaderStructure(
|
||||
const std::string &structureName,
|
||||
const void *offset,
|
||||
const enum ShaderOpenGLStructureType structureType,
|
||||
std::function<
|
||||
void(const T&, std::vector<struct ShaderParameter>&)
|
||||
> getParameters,
|
||||
size_t count = 1
|
||||
) {
|
||||
this->structureName = structureName;
|
||||
this->offset = (size_t)offset;
|
||||
this->structureType = structureType;
|
||||
this->size = sizeof(T);
|
||||
this->count = count;
|
||||
this->parameters = std::vector<struct ShaderParameter>();
|
||||
|
||||
T dummy;
|
||||
getParameters(dummy, this->parameters);
|
||||
|
||||
// Update offsets.
|
||||
auto itParams = this->parameters.begin();
|
||||
while(itParams != this->parameters.end()) {
|
||||
struct ShaderParameter ¶m = *itParams;
|
||||
param.offset -= (size_t)(&dummy);
|
||||
|
||||
// Check for non-aligned OpenGL structures.
|
||||
if(param.offset % sizeof(glm::vec4) != 0) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
if(
|
||||
itParams == (this->parameters.end() - 1) &&
|
||||
count > 1 &&
|
||||
(sizeof(T) % sizeof(glm::vec4)) != 0
|
||||
) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on last element in array structure on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
++itParams;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -1,230 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/SimpleTexturedShader.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include "slang.h"
|
||||
#include "slang-gfx.h"
|
||||
using namespace slang;
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void SimpleTexturedShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
std::string shader = R"(
|
||||
cbuffer Uniforms {
|
||||
float4x4 u_Projection;
|
||||
float4x4 u_View;
|
||||
float4x4 u_Model;
|
||||
float4 u_Color;
|
||||
bool u_HasTexture;
|
||||
uniform Sampler2D u_Texture;
|
||||
};
|
||||
|
||||
struct AssembledVertex {
|
||||
float3 position : POSITION;
|
||||
float2 texcoord : TEXCOORD;
|
||||
};
|
||||
|
||||
struct Fragment {
|
||||
float4 color;
|
||||
};
|
||||
|
||||
struct VertexStageOutput {
|
||||
float2 uv : UV;
|
||||
float4 sv_position : SV_Position;
|
||||
};
|
||||
|
||||
[shader("vertex")]
|
||||
VertexStageOutput vertexMain(
|
||||
AssembledVertex assembledVertex
|
||||
) {
|
||||
VertexStageOutput output;
|
||||
|
||||
float3 position = assembledVertex.position;
|
||||
|
||||
output.uv = assembledVertex.texcoord;
|
||||
|
||||
output.sv_position = mul(
|
||||
float4(position, 1.0),
|
||||
mul(u_Model, mul(u_View, u_Projection))
|
||||
);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
[shader("fragment")]
|
||||
Fragment fragmentMain(
|
||||
float2 uv: UV
|
||||
) : SV_Target {
|
||||
Fragment output;
|
||||
if(u_HasTexture) {
|
||||
output.color = u_Texture.Sample(uv) * u_Color;
|
||||
} else {
|
||||
output.color = u_Color;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
)";
|
||||
Slang::ComPtr<IGlobalSession> globalSession;
|
||||
createGlobalSession(globalSession.writeRef());
|
||||
|
||||
SessionDesc sessionDesc;
|
||||
|
||||
TargetDesc targetDesc;
|
||||
targetDesc.format = SLANG_GLSL;
|
||||
targetDesc.profile = globalSession->findProfile("glsl_330");
|
||||
sessionDesc.targets = &targetDesc;
|
||||
sessionDesc.targetCount = 1;
|
||||
|
||||
Slang::ComPtr<IBlob> diagnostics;
|
||||
const char* searchPaths[] = { "/home/yourwishes/htdocs/Dawn/assets/shaders/" };
|
||||
sessionDesc.searchPaths = searchPaths;
|
||||
sessionDesc.searchPathCount = 1;
|
||||
|
||||
Slang::ComPtr<ISession> session;
|
||||
globalSession->createSession(sessionDesc, session.writeRef());
|
||||
auto module = session->loadModuleFromSourceString(
|
||||
"hello-world.slang",
|
||||
"hello-world.slang",
|
||||
shader.c_str(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("Failed to load module %s", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
Slang::ComPtr<IEntryPoint> vertexEntryPoint;
|
||||
Slang::ComPtr<IEntryPoint> fragEntryPoint;
|
||||
module->findEntryPointByName("vertexMain", vertexEntryPoint.writeRef());
|
||||
module->findEntryPointByName("fragmentMain", fragEntryPoint.writeRef());
|
||||
|
||||
IComponentType* components[] = { module, vertexEntryPoint, fragEntryPoint };
|
||||
Slang::ComPtr<IComponentType> program;
|
||||
session->createCompositeComponentType(
|
||||
components,
|
||||
sizeof(components) / sizeof(components[0]),
|
||||
program.writeRef()
|
||||
);
|
||||
|
||||
Slang::ComPtr<IComponentType> linkedProgram;
|
||||
auto result = program->link(linkedProgram.writeRef(), diagnostics.writeRef());
|
||||
std::cout << "Result: " << result << std::endl;
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
int entryPointIndex = 0;
|
||||
int targetIndex = 0; // only one target
|
||||
Slang::ComPtr<IBlob> vertexBlob;
|
||||
result = linkedProgram->getEntryPointCode(
|
||||
entryPointIndex,
|
||||
targetIndex,
|
||||
vertexBlob.writeRef(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
slang::ProgramLayout* layout = program->getLayout();
|
||||
unsigned parameterCount = layout->getParameterCount();
|
||||
for(unsigned pp = 0; pp < parameterCount; pp++) {
|
||||
slang::VariableLayoutReflection* parameter = layout->getParameterByIndex(pp);
|
||||
std::cout << "Parameter: " << parameter->getName() << std::endl;
|
||||
|
||||
auto layout = parameter->getTypeLayout();
|
||||
auto fields = layout->getFieldCount();
|
||||
for(unsigned ff = 0; ff < fields; ff++) {
|
||||
slang::VariableLayoutReflection* field = layout->getFieldByIndex(ff);
|
||||
std::string fieldName = field->getName();
|
||||
std::cout << "Field: " << fieldName << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
std::string vertexString = (const char*)vertexBlob->getBufferPointer();
|
||||
|
||||
entryPointIndex = 1;
|
||||
Slang::ComPtr<IBlob> fragmentBlob;
|
||||
result = linkedProgram->getEntryPointCode(
|
||||
entryPointIndex,
|
||||
targetIndex,
|
||||
fragmentBlob.writeRef(),
|
||||
diagnostics.writeRef()
|
||||
);
|
||||
if(diagnostics) {
|
||||
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
|
||||
return;
|
||||
}
|
||||
|
||||
std::string fragmentString = (const char*)fragmentBlob->getBufferPointer();
|
||||
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX, vertexString
|
||||
);
|
||||
stages.push_back(vertex);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT, fragmentString
|
||||
);
|
||||
stages.push_back(fragment);
|
||||
|
||||
structures.push_back(ShaderStructure<struct SimpleTexturedShaderDataSub>(
|
||||
"block_SLANG_ParameterGroup_Uniforms_std140_0",
|
||||
&rel->data,
|
||||
ShaderOpenGLStructureType::STD140,
|
||||
[](const SimpleTexturedShaderDataSub &data, std::vector<struct ShaderParameter> ¶meters) {
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection_0",
|
||||
&data.projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View_0",
|
||||
&data.view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model_0",
|
||||
&data.model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Color_0",
|
||||
&data.color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_HasTexture_0",
|
||||
&data.hasTexture,
|
||||
ShaderParameterType::BOOLEAN
|
||||
));
|
||||
}
|
||||
));
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"Uniforms_u_Texture_0",
|
||||
&rel->texture,
|
||||
ShaderParameterType::TEXTURE
|
||||
));
|
||||
}
|
||||
@@ -1,34 +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/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct SimpleTexturedShaderDataSub {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
struct Color color = COLOR_WHITE;
|
||||
|
||||
bool hasTexture = false;
|
||||
};
|
||||
|
||||
struct SimpleTexturedShaderData {
|
||||
struct SimpleTexturedShaderDataSub data;
|
||||
shadertexturebinding_t texture = 0;
|
||||
};
|
||||
|
||||
class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,194 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/Macro.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void UIShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct UIShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
switch(variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX,
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||
"uniform mat4 u_Projection;\n"
|
||||
"uniform mat4 u_View;\n"
|
||||
"uniform mat4 u_Model;\n"
|
||||
"struct UIShaderQuad {\n"
|
||||
"vec4 quad;\n"
|
||||
"vec4 uv;\n"
|
||||
"vec4 color;\n"
|
||||
"vec4 style;\n"
|
||||
"};\n"
|
||||
"layout (std140) uniform ub_Quad {\n"
|
||||
"UIShaderQuad quads[" MACRO_STRINGIFY(UI_SHADER_QUAD_COUNT) "];\n"
|
||||
"};\n"
|
||||
"out vec2 v_TextCoord;\n"
|
||||
"out vec4 v_Color;\n"
|
||||
"out vec4 v_Style;\n"
|
||||
"void main() {\n"
|
||||
"vec4 pos;\n"
|
||||
"vec2 coord;\n"
|
||||
"int index = int(aPos.z);\n"
|
||||
"int quadIndex = index / 4;\n"
|
||||
"int vertexIndex = index % 4;\n"
|
||||
"UIShaderQuad quad = quads[quadIndex];\n"
|
||||
"if(vertexIndex == 0) {\n"
|
||||
"pos.x = quad.quad.x;\n"
|
||||
"pos.y = quad.quad.y;\n"
|
||||
"coord.x = quad.uv.x;\n"
|
||||
"coord.y = quad.uv.y;\n"
|
||||
"} else if(vertexIndex == 1) {\n"
|
||||
"pos.x = quad.quad.z;\n"
|
||||
"pos.y = quad.quad.y;\n"
|
||||
"coord.x = quad.uv.z;\n"
|
||||
"coord.y = quad.uv.y;\n"
|
||||
"} else if(vertexIndex == 2) {\n"
|
||||
"pos.y = quad.quad.w;\n"
|
||||
"pos.x = quad.quad.x;\n"
|
||||
"coord.x = quad.uv.x;\n"
|
||||
"coord.y = quad.uv.w;\n"
|
||||
"} else if(vertexIndex == 3) {\n"
|
||||
"pos.x = quad.quad.z;\n"
|
||||
"pos.y = quad.quad.w;\n"
|
||||
"coord.x = quad.uv.z;\n"
|
||||
"coord.y = quad.uv.w;\n"
|
||||
"}\n"
|
||||
"pos.z = 0;\n"
|
||||
"pos.w = 1;\n"
|
||||
"gl_Position = u_Projection * u_View * u_Model * pos;\n"
|
||||
"v_TextCoord = coord;\n"
|
||||
"v_Color = quad.color;\n"
|
||||
"v_Style = quad.style;\n"
|
||||
"}"
|
||||
);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT,
|
||||
"#version 330 core\n"
|
||||
"in vec2 v_TextCoord;\n"
|
||||
"in vec4 v_Color;\n"
|
||||
"in vec4 v_Style;\n"
|
||||
"uniform sampler2D u_Texture[" MACRO_STRINGIFY(UI_SHADER_TEXTURE_COUNT) "];\n"
|
||||
"out vec4 o_Color;\n"
|
||||
"void main() {\n"
|
||||
"vec4 texColor = vec4(1, 1, 1, 1);\n"
|
||||
"int vStyle = int(round(v_Style[0]));\n"
|
||||
"int vTextInd = int(round(v_Style[1]));\n"
|
||||
"switch(vTextInd) {\n"
|
||||
"case -1:\n"
|
||||
"texColor = vec4(1, 1, 1, 1);\n"
|
||||
"break;\n"
|
||||
"case 0:\n"
|
||||
"texColor = texture(u_Texture[0], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 1:\n"
|
||||
"texColor = texture(u_Texture[1], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 2:\n"
|
||||
"texColor = texture(u_Texture[2], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 3:\n"
|
||||
"texColor = texture(u_Texture[3], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 4:\n"
|
||||
"texColor = texture(u_Texture[4], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"case 5:\n"
|
||||
"texColor = texture(u_Texture[5], v_TextCoord);\n"
|
||||
"break;\n"
|
||||
"}\n"
|
||||
"switch(vStyle) {\n"
|
||||
"case 0:\n"
|
||||
"o_Color = texColor * v_Color;\n"
|
||||
"break;\n"
|
||||
"case 1:\n"
|
||||
"o_Color.rgb = v_Color.rgb;\n"
|
||||
"o_Color.a = texColor.r * v_Color.a;\n"
|
||||
"break;\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Texture",
|
||||
&rel->textures,
|
||||
ShaderParameterType::TEXTURE,
|
||||
UI_SHADER_TEXTURE_COUNT
|
||||
));
|
||||
|
||||
structures.push_back(ShaderStructure<struct UIShaderQuad>(
|
||||
"ub_Quad",
|
||||
&rel->quads,
|
||||
ShaderOpenGLStructureType::STD140,
|
||||
[&](const struct UIShaderQuad &rel, std::vector<struct ShaderParameter> ¶meters) {
|
||||
parameters.push_back(ShaderParameter(
|
||||
"quad",
|
||||
&rel.quad,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"uv",
|
||||
&rel.uv,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"color",
|
||||
&rel.color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"style",
|
||||
&rel.style,
|
||||
ShaderParameterType::VEC4
|
||||
));
|
||||
},
|
||||
UI_SHADER_QUAD_COUNT
|
||||
));
|
||||
}
|
||||
@@ -1,43 +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/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
#define UI_SHADER_QUAD_COUNT 1024
|
||||
#define UI_SHADER_TEXTURE_COUNT 16
|
||||
|
||||
enum class UIShaderQuadStyle {
|
||||
TEXTURED = 0,
|
||||
FONT = 1
|
||||
};
|
||||
|
||||
struct UIShaderQuad {
|
||||
glm::vec4 quad;
|
||||
glm::vec4 uv;
|
||||
struct Color color;
|
||||
glm::vec4 style;
|
||||
};
|
||||
|
||||
struct UIShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
shadertexturebinding_t textures[UI_SHADER_TEXTURE_COUNT];
|
||||
struct UIShaderQuad quads[UI_SHADER_QUAD_COUNT];
|
||||
};
|
||||
|
||||
class UIShader : public Shader<UIShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct UIShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -11,7 +11,6 @@ target_include_directories(${DAWN_TARGET_NAME}
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(component)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(game)
|
||||
add_subdirectory(rpg)
|
||||
|
||||
|
||||
@@ -10,5 +10,4 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
RPGMap.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
# Subdirs
|
||||
@@ -1,7 +0,0 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(material)
|
||||
@@ -1,9 +0,0 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
MapMaterial.cpp
|
||||
)
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "MapMaterial.hpp"
|
||||
#include "util/JSON.hpp"
|
||||
#include "asset/loader/TextureLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::vector<
|
||||
std::shared_ptr<IShaderBase>
|
||||
> MapMaterial::getLockedShaders(ShaderManager &shaderManager) {
|
||||
return {
|
||||
shaderManager.getShader<MapShader>()
|
||||
};
|
||||
}
|
||||
|
||||
void MapMaterial::load(std::shared_ptr<SceneLoadContext> ctx) {
|
||||
if(ctx->data.contains("color")) {
|
||||
this->setColor(JSON::color(ctx->data["color"]));
|
||||
}
|
||||
|
||||
if(ctx->data.contains("texture")) {
|
||||
auto asset = ctx->getAsset<TextureLoader>(
|
||||
ctx->data["texture"].get<std::string>()
|
||||
);
|
||||
this->setTexture(asset->getTexture());
|
||||
}
|
||||
}
|
||||
|
||||
struct Color MapMaterial::getColor() {
|
||||
return this->data.color;
|
||||
}
|
||||
|
||||
std::shared_ptr<Texture> MapMaterial::getTexture() {
|
||||
return this->texture;
|
||||
}
|
||||
|
||||
void MapMaterial::setTexture(
|
||||
const std::shared_ptr<Texture> texture
|
||||
) {
|
||||
this->texture = texture;
|
||||
}
|
||||
|
||||
void MapMaterial::setColor(const struct Color color) {
|
||||
this->data.color = color;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> MapMaterial::getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) {
|
||||
this->data.model = this->getItem()->getWorldTransform();
|
||||
this->data.projection = ctx.camera->getProjection();
|
||||
this->data.view = ctx.camera->getItem()->getWorldTransform();
|
||||
auto textures = std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
>();
|
||||
|
||||
if(this->texture) {
|
||||
this->data.hasTexture = true;
|
||||
this->data.texture = 0;
|
||||
textures[this->data.texture] = this->texture;
|
||||
} else {
|
||||
this->data.hasTexture = false;
|
||||
}
|
||||
|
||||
return {
|
||||
createRenderPass<MapShader, struct MapShaderData>(
|
||||
*this,
|
||||
data,
|
||||
textures
|
||||
)
|
||||
};
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "component/display/material/Material.hpp"
|
||||
#include "display/shader/MapShader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class MapMaterial : public Material {
|
||||
protected:
|
||||
std::vector<std::shared_ptr<IShaderBase>> getLockedShaders(
|
||||
ShaderManager &shaderManager
|
||||
) override;
|
||||
|
||||
private:
|
||||
struct MapShaderData data;
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
public:
|
||||
void load(std::shared_ptr<SceneLoadContext> ctx) override;
|
||||
|
||||
/**
|
||||
* Returns the color of this material.
|
||||
*/
|
||||
struct Color getColor();
|
||||
|
||||
/**
|
||||
* Returns the texture of this material.
|
||||
*
|
||||
* @return The texture of this material.
|
||||
*/
|
||||
std::shared_ptr<Texture> getTexture();
|
||||
|
||||
/**
|
||||
* Sets the texture of this material.
|
||||
*
|
||||
* @param texture The texture to set.
|
||||
*/
|
||||
void setTexture(const std::shared_ptr<Texture> texture);
|
||||
|
||||
/**
|
||||
* Sets the color of this material.
|
||||
*
|
||||
* @param color The color to set.
|
||||
*/
|
||||
void setColor(const struct Color color);
|
||||
|
||||
std::vector<std::shared_ptr<IRenderPass>> getPasses(
|
||||
struct RenderPassContext &ctx
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(shader)
|
||||
@@ -1,106 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/MapShader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void MapShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct MapShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
std::cout << "MapShader::getStages" << std::endl;
|
||||
|
||||
switch(variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX,R"(
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoord;
|
||||
uniform mat4 u_Projection;
|
||||
uniform mat4 u_View;
|
||||
uniform mat4 u_Model;
|
||||
out vec2 o_TextCoord;
|
||||
void main() {
|
||||
gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);
|
||||
o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);
|
||||
}
|
||||
)"
|
||||
);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT,R"(
|
||||
#version 330 core
|
||||
in vec2 o_TextCoord;
|
||||
out vec4 o_Color;
|
||||
uniform vec4 u_Color;
|
||||
uniform bool u_HasTexture;
|
||||
uniform sampler2D u_Texture;
|
||||
void main() {
|
||||
if(u_HasTexture) {
|
||||
o_Color = texture(u_Texture, o_TextCoord);
|
||||
} else {
|
||||
o_Color = u_Color;
|
||||
}
|
||||
|
||||
if(o_Color.a == 0) discard;
|
||||
}
|
||||
)"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Color",
|
||||
&rel->color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_HasTexture",
|
||||
&rel->hasTexture,
|
||||
ShaderParameterType::BOOLEAN
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Texture",
|
||||
&rel->texture,
|
||||
ShaderParameterType::TEXTURE
|
||||
));
|
||||
}
|
||||
@@ -1,29 +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/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct MapShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
struct Color color = COLOR_WHITE;
|
||||
bool hasTexture = false;
|
||||
shadertexturebinding_t texture = 0;
|
||||
};
|
||||
|
||||
class MapShader : public Shader<MapShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct MapShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
||||
@@ -6,13 +6,10 @@
|
||||
#include "Game.hpp"
|
||||
#include "component/SceneComponentRegistry.hpp"
|
||||
|
||||
#include "component/display/material/MapMaterial.hpp"
|
||||
#include "component/RPGEntity.hpp"
|
||||
#include "component/RPGPlayer.hpp"
|
||||
#include "component/RPGMap.hpp"
|
||||
|
||||
#include "asset/loader/ShaderLoader.hpp"
|
||||
#include <fstream>
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
@@ -20,7 +17,6 @@ Game::Game() : IGame() {
|
||||
SceneComponentRegistry::reg<RPGEntity>("RPGEntity");
|
||||
SceneComponentRegistry::reg<RPGPlayer>("RPGPlayer");
|
||||
SceneComponentRegistry::reg<RPGMap>("RPGMap");
|
||||
SceneComponentRegistry::reg<MapMaterial>("MapMaterial");
|
||||
}
|
||||
|
||||
std::string Game::getInitialScene() {
|
||||
@@ -33,16 +29,6 @@ void Game::initManagers() {
|
||||
|
||||
auto sl = assetManager->get<ShaderLoader>("shaders/hello-world.slang");
|
||||
sl->loadImmediately();
|
||||
|
||||
// auto code1 = sl->getEntryPointCode("vertexMain");
|
||||
// std::fstream file("vertexMain.glsl", std::ios::out);
|
||||
// file << code1;
|
||||
// file.close();
|
||||
|
||||
// auto code2 = sl->getEntryPointCode("fragmentMain");
|
||||
// std::fstream file2("fragmentMain.glsl", std::ios::out);
|
||||
// file2 << code2;
|
||||
// file2.close();
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
|
||||
Reference in New Issue
Block a user