Base refactor
This commit is contained in:
@ -1,17 +0,0 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
RenderPipeline.cpp
|
||||
Tileset.cpp
|
||||
Color.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(font)
|
||||
add_subdirectory(mesh)
|
||||
add_subdirectory(shader)
|
@ -1,83 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "util/parser/TypeParsers.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
struct Color Color::fromString(const std::string str) {
|
||||
// Convert to lowercase
|
||||
auto lower = stringToLowercase(str);
|
||||
|
||||
if(stringIncludes(lower, "cornflower")) {
|
||||
return COLOR_CORNFLOWER_BLUE;
|
||||
|
||||
} else if(stringIncludes(lower, "magenta")) {
|
||||
return COLOR_MAGENTA;
|
||||
|
||||
} else if(stringIncludes(lower, "white")) {
|
||||
return COLOR_WHITE;
|
||||
|
||||
} else if(stringIncludes(lower, "black")) {
|
||||
return COLOR_BLACK;
|
||||
|
||||
} else if(stringIncludes(lower, "red")) {
|
||||
return COLOR_RED;
|
||||
|
||||
} else if(stringIncludes(lower, "green")) {
|
||||
return COLOR_GREEN;
|
||||
|
||||
} else if(stringIncludes(lower, "blue")) {
|
||||
return COLOR_BLUE;
|
||||
|
||||
} else if(stringIncludes(lower, "transparent")) {
|
||||
return COLOR_TRANSPARENT;
|
||||
}
|
||||
|
||||
// Hex code?
|
||||
if(lower[0] == '#') {
|
||||
// Remove the hash
|
||||
lower = lower.substr(1);
|
||||
|
||||
// Convert to RGB
|
||||
if(lower.length() == 3) {
|
||||
// Convert to 6 digit hex
|
||||
lower = lower[0] + lower[0] + lower[1] + lower[1] + lower[2] + lower[2];
|
||||
}
|
||||
|
||||
// Convert to RGB
|
||||
return {
|
||||
(float_t)std::stoi(lower.substr(0, 2), nullptr, 16) / 255.0f,
|
||||
(float_t)std::stoi(lower.substr(2, 2), nullptr, 16) / 255.0f,
|
||||
(float_t)std::stoi(lower.substr(4, 2), nullptr, 16) / 255.0f,
|
||||
1.0f
|
||||
};
|
||||
}
|
||||
|
||||
// Split by comma
|
||||
auto splitByComma = stringSplit(str, ",");
|
||||
if(splitByComma.size() == 3) {
|
||||
// RGB
|
||||
return {
|
||||
(float_t)std::stof(splitByComma[0]),
|
||||
(float_t)std::stof(splitByComma[1]),
|
||||
(float_t)std::stof(splitByComma[2]),
|
||||
1.0f
|
||||
};
|
||||
} else if(splitByComma.size() == 4) {
|
||||
// RGBA
|
||||
return {
|
||||
(float_t)std::stof(splitByComma[0]),
|
||||
(float_t)std::stof(splitByComma[1]),
|
||||
(float_t)std::stof(splitByComma[2]),
|
||||
(float_t)std::stof(splitByComma[3])
|
||||
};
|
||||
}
|
||||
|
||||
// TODO: Parse other kinds of colors
|
||||
assertUnreachable("Failed to find a color match for %s", str);
|
||||
return {};
|
||||
}
|
@ -1,90 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/string.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ColorU8 {
|
||||
uint8_t r, g, b, a;
|
||||
};
|
||||
|
||||
#pragma pack(push, 4)
|
||||
struct Color {
|
||||
/**
|
||||
* Returns a color from a string.
|
||||
*
|
||||
* @param str String to parse.
|
||||
* @return Color parsed.
|
||||
*/
|
||||
static struct Color fromString(const std::string str);
|
||||
|
||||
float_t r, g, b, a;
|
||||
|
||||
const struct Color& operator = (const struct Color &val) {
|
||||
this->r = val.r;
|
||||
this->g = val.g;
|
||||
this->b = val.b;
|
||||
this->a = val.a;
|
||||
return *this;
|
||||
}
|
||||
|
||||
struct Color operator * (const float_t &x) {
|
||||
return {
|
||||
r * x,
|
||||
g * x,
|
||||
b * x,
|
||||
a * x
|
||||
};
|
||||
}
|
||||
|
||||
struct Color operator - (const struct Color &color) {
|
||||
return {
|
||||
r - color.r,
|
||||
g - color.g,
|
||||
b - color.b,
|
||||
a - color.a
|
||||
};
|
||||
}
|
||||
|
||||
struct Color operator + (const struct Color &color) {
|
||||
return {
|
||||
r + color.r,
|
||||
g + color.g,
|
||||
b + color.b,
|
||||
a + color.a
|
||||
};
|
||||
}
|
||||
|
||||
const bool_t operator == (const struct Color &other) {
|
||||
return r == other.r && g == other.g && b == other.b && a == other.a;
|
||||
}
|
||||
|
||||
operator struct ColorU8() const {
|
||||
return {
|
||||
(uint8_t)(r * 255),
|
||||
(uint8_t)(g * 255),
|
||||
(uint8_t)(b * 255),
|
||||
(uint8_t)(a * 255)
|
||||
};
|
||||
}
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#define COLOR_DEF(r,g,b,a) { r, g, b, a }
|
||||
#define COLOR_WHITE COLOR_DEF(1.0f, 1.0f, 1.0f, 1.0f)
|
||||
#define COLOR_RED COLOR_DEF(1.0f, 0, 0, 1.0f)
|
||||
#define COLOR_GREEN COLOR_DEF(0, 1.0f, 0, 1.0f)
|
||||
#define COLOR_BLUE COLOR_DEF(0, 0, 1.0f, 1.0f)
|
||||
#define COLOR_BLACK COLOR_DEF(0, 0, 0, 1.0f)
|
||||
#define COLOR_MAGENTA COLOR_DEF(1.0f, 0, 1.0f, 1.0f)
|
||||
#define COLOR_DARK_GREY COLOR_DEF(0.2f, 0.2f, 0.2f, 1.0f)
|
||||
#define COLOR_LIGHT_GREY COLOR_DEF(0.8f, 0.8f, 0.8f, 1.0f)
|
||||
#define COLOR_CORNFLOWER_BLUE COLOR_DEF(0.4f, 0.6f, 0.9f, 1.0f)
|
||||
#define COLOR_WHITE_TRANSPARENT COLOR_DEF(1.0f, 1.0f, 1.0f, 0.0f)
|
||||
#define COLOR_BLACK_TRANSPARENT COLOR_DEF(0.0f, 0.0f, 0.0f, 0.0f)
|
||||
#define COLOR_TRANSPARENT COLOR_WHITE_TRANSPARENT
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0)
|
||||
#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
class RenderPipeline;
|
||||
class ShaderManager;
|
||||
|
||||
class IRenderManager : public std::enable_shared_from_this<IRenderManager> {
|
||||
protected:
|
||||
flag_t renderFlags = 0;
|
||||
|
||||
public:
|
||||
std::weak_ptr<DawnGame> game;
|
||||
|
||||
/**
|
||||
* Default constructor for a render manager instance.
|
||||
*
|
||||
* @param game Game that this render manager belongs to.
|
||||
*/
|
||||
IRenderManager() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the primary render target (the backbuffer) that draws directly
|
||||
* to the screen.
|
||||
*
|
||||
* @return Shared pointer to the backbuffer render target.
|
||||
*/
|
||||
virtual std::shared_ptr<RenderTarget> getBackBuffer() = 0;
|
||||
|
||||
/**
|
||||
* Returns the current render pipeline intended to be used for rendering
|
||||
* the currently active scene on the game instance.
|
||||
*
|
||||
* @return Reference to the currently active main scene render pipeline.
|
||||
*/
|
||||
virtual std::shared_ptr<RenderPipeline> getRenderPipeline() = 0;
|
||||
|
||||
/**
|
||||
* Returns the shader manager that this render manager uses.
|
||||
*
|
||||
* @return Reference to the shader manager.
|
||||
*/
|
||||
virtual std::shared_ptr<ShaderManager> getShaderManager() = 0;
|
||||
|
||||
/**
|
||||
* Sets the render flags for the render manager to use.
|
||||
*
|
||||
* @param renderFlags Render flags to use.
|
||||
*/
|
||||
virtual void setRenderFlags(const flag_t renderFlags) = 0;
|
||||
|
||||
/**
|
||||
* Initialize / Start the Render Manager.
|
||||
*
|
||||
* @param game Game instance this render manager belongs to.
|
||||
*/
|
||||
virtual void init(const std::weak_ptr<DawnGame> game) = 0;
|
||||
|
||||
/**
|
||||
* Perform a synchronous frame update on the render manager.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
/**
|
||||
* Clean up the render manager.
|
||||
*/
|
||||
virtual ~IRenderManager() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
@ -1,115 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Color.hpp"
|
||||
#include "state/StateOwner.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum TextureFormat {
|
||||
TEXTURE_FORMAT_R = 1,
|
||||
TEXTURE_FORMAT_RG = 2,
|
||||
TEXTURE_FORMAT_RGB = 3,
|
||||
TEXTURE_FORMAT_RGBA = 4
|
||||
};
|
||||
|
||||
enum TextureWrapMode {
|
||||
TEXTURE_WRAP_MODE_REPEAT = 0,
|
||||
TEXTURE_WRAP_MODE_MIRRORED_REPEAT = 1,
|
||||
TEXTURE_WRAP_MODE_CLAMP_TO_EDGE = 2,
|
||||
TEXTURE_WRAP_MODE_CLAMP_TO_BORDER = 3
|
||||
};
|
||||
|
||||
enum TextureFilterMode {
|
||||
TEXTURE_FILTER_MODE_NEAREST = 0,
|
||||
TEXTURE_FILTER_MODE_LINEAR = 1
|
||||
};
|
||||
|
||||
enum TextureDataFormat {
|
||||
TEXTURE_DATA_FORMAT_UNSIGNED_BYTE = 0,
|
||||
TEXTURE_DATA_FORMAT_FLOAT = 1
|
||||
};
|
||||
|
||||
class ITexture : public StateOwner {
|
||||
protected:
|
||||
bool_t texturePropertiesNeedUpdating = true;
|
||||
|
||||
public:
|
||||
StateProperty<enum TextureWrapMode> wrapModeX;
|
||||
StateProperty<enum TextureWrapMode> wrapModeY;
|
||||
StateProperty<enum TextureFilterMode> filterModeMin;
|
||||
StateProperty<enum TextureFilterMode> filterModeMag;
|
||||
StateProperty<enum TextureFilterMode> mipmapFilterModeMin;
|
||||
StateProperty<enum TextureFilterMode> mipmapFilterModeMag;
|
||||
|
||||
ITexture() :
|
||||
wrapModeX(TEXTURE_WRAP_MODE_CLAMP_TO_EDGE),
|
||||
wrapModeY(TEXTURE_WRAP_MODE_CLAMP_TO_EDGE),
|
||||
filterModeMin(TEXTURE_FILTER_MODE_LINEAR),
|
||||
filterModeMag(TEXTURE_FILTER_MODE_LINEAR),
|
||||
mipmapFilterModeMin(TEXTURE_FILTER_MODE_NEAREST),
|
||||
mipmapFilterModeMag(TEXTURE_FILTER_MODE_NEAREST)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the width of the texture.
|
||||
*
|
||||
* @return Width of the texture.
|
||||
*/
|
||||
virtual int32_t getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Returns the height of the texture.
|
||||
*
|
||||
* @return Height of the texture.
|
||||
*/
|
||||
virtual int32_t getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Initializes a texture.
|
||||
*
|
||||
* @param width Width of the texture (in pixels).
|
||||
* @param height Height of the texture (in pixels).
|
||||
* @param format Data format of the texture to use.
|
||||
* @param dataFormat Data format of the texture to use.
|
||||
*/
|
||||
virtual void setSize(
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const enum TextureFormat format,
|
||||
const enum TextureDataFormat dataFormat
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Fill a texture with a single color. This is stupidly costly.
|
||||
*
|
||||
* @param color Color to fill.
|
||||
*/
|
||||
virtual void fill(const struct Color) = 0;
|
||||
virtual void fill(const uint8_t) = 0;
|
||||
|
||||
/**
|
||||
* Returns true only when the texture has been loaded, sized and put on
|
||||
* the gpu for rendering.
|
||||
*
|
||||
* @return True if ready, otherwise false.
|
||||
*/
|
||||
virtual bool_t isReady() = 0;
|
||||
|
||||
/**
|
||||
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
|
||||
* avoid doing this too often.
|
||||
*
|
||||
* @param pixels Array of pixels you're trying to buffer.
|
||||
* @return The amount of bytes buffered to the texture.
|
||||
*/
|
||||
virtual void buffer(const struct ColorU8 pixels[]) = 0;
|
||||
virtual void buffer(const uint8_t pixels[]) = 0;
|
||||
|
||||
virtual ~ITexture() {
|
||||
}
|
||||
};
|
||||
}
|
@ -1,262 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RenderPipeline.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "scene/components/scene/SubSceneController.hpp"
|
||||
|
||||
#if DAWN_DEBUG_BUILD
|
||||
#include "scene/debug/SceneDebugLine.hpp"
|
||||
#endif
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPipeline::RenderPipeline() {
|
||||
}
|
||||
|
||||
void RenderPipeline::init(const std::weak_ptr<RenderManager> renderManager) {
|
||||
this->renderManager = renderManager;
|
||||
shaderBuffer.init();
|
||||
}
|
||||
|
||||
void RenderPipeline::render() {
|
||||
auto rm = renderManager.lock();
|
||||
assertNotNull(rm, "RenderManager cannot be null");
|
||||
auto game = rm->game.lock();
|
||||
assertNotNull(game, "Game cannot be null");
|
||||
|
||||
if(game->scene != nullptr) {
|
||||
renderScene(game->scene);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::renderScene(const std::shared_ptr<Scene> scene) {
|
||||
assertNotNull(scene, "Scene cannot be null");
|
||||
auto rm = renderManager.lock();
|
||||
assertNotNull(rm, "RenderManager cannot be null");
|
||||
|
||||
// Render subscenes first.
|
||||
auto subSceneControllers = scene->findComponents<SubSceneController>();
|
||||
auto itSubScene = subSceneControllers.begin();
|
||||
while(itSubScene != subSceneControllers.end()) {
|
||||
auto subScene = (*itSubScene)->subScene;
|
||||
if(subScene == nullptr) {
|
||||
++itSubScene;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
(*itSubScene)->onlyUpdateUnpaused &&
|
||||
scene->game.lock()->timeManager.isPaused
|
||||
) {
|
||||
++itSubScene;
|
||||
continue;
|
||||
}
|
||||
|
||||
renderScene(subScene);
|
||||
++itSubScene;
|
||||
}
|
||||
|
||||
// Now render backbuffers.
|
||||
auto backBuffer = rm->getBackBuffer();
|
||||
auto cameras = scene->findComponents<Camera>();
|
||||
std::shared_ptr<Camera> backBufferCamera;
|
||||
|
||||
// First, render all non-backbuffer cameras.
|
||||
auto it = cameras.begin();
|
||||
while(it != cameras.end()) {
|
||||
auto cameraTarget = (*it)->getRenderTarget();
|
||||
|
||||
// Leave the backbuffer camera(s) to last, so we skip them. we do this so
|
||||
// that children framebuffers contain the CURRENT frame, not LAST frame.
|
||||
if(cameraTarget == nullptr) {
|
||||
++it;
|
||||
continue;
|
||||
} else if(cameraTarget == backBuffer) {
|
||||
backBufferCamera = *it;
|
||||
} else {
|
||||
renderSceneCamera(scene, *it);
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
// Now render the backbuffer camera.
|
||||
if(backBufferCamera == nullptr) return;
|
||||
renderSceneCamera(scene, backBufferCamera);
|
||||
}
|
||||
|
||||
void RenderPipeline::renderSceneCamera(
|
||||
const std::shared_ptr<Scene> scene,
|
||||
const std::shared_ptr<Camera> camera
|
||||
) {
|
||||
auto rm = renderManager.lock();
|
||||
assertNotNull(rm, "RenderManager cannot be null");
|
||||
|
||||
std::vector<struct ShaderPassItem>::iterator itPassItem;
|
||||
|
||||
assertNotNull(scene, "Scene cannot be null");
|
||||
assertNotNull(camera, "Camera cannot be null");
|
||||
|
||||
// Create a new render ID. Long story short this is a really dirty way of
|
||||
// not sending parameters to shaders more than we need.
|
||||
renderId--;
|
||||
|
||||
// Get the render target.
|
||||
auto renderTarget = camera->getRenderTarget();
|
||||
assertNotNull(renderTarget, "Camera must have a render target");
|
||||
|
||||
// Update shader parameter buffers with current knowledge
|
||||
struct RenderPipelineShaderBufferData shaderBufferData;
|
||||
shaderBufferData.projection = camera->getProjection();
|
||||
shaderBufferData.view = camera->item.lock()->getWorldTransform();
|
||||
shaderBuffer.buffer(&shaderBufferData);
|
||||
|
||||
// Prepare a render context. This is just a nice way of letting renderables
|
||||
// know a bit about what is happening, they can choose to use this data to
|
||||
// render themselves differently.
|
||||
struct IRenderableContext context = {
|
||||
scene,
|
||||
camera,
|
||||
shared_from_this()
|
||||
};
|
||||
|
||||
// Get the list of things to render first.
|
||||
std::vector<struct ShaderPassItem> shaderPassItems;
|
||||
|
||||
// Renderables
|
||||
auto renderables = scene->findComponents<IRenderable>();
|
||||
auto itRenderables = renderables.begin();
|
||||
while(itRenderables != renderables.end()) {
|
||||
vectorAppend(shaderPassItems, (*itRenderables)->getRenderPasses(context));
|
||||
++itRenderables;
|
||||
}
|
||||
|
||||
// Inject index into each item
|
||||
itPassItem = shaderPassItems.begin();
|
||||
while(itPassItem != shaderPassItems.end()) {
|
||||
itPassItem->index = itPassItem;
|
||||
++itPassItem;
|
||||
}
|
||||
|
||||
// Now we've queued everything, let's sort the rendering queue by the priority
|
||||
std::sort(
|
||||
shaderPassItems.begin(),
|
||||
shaderPassItems.end(),
|
||||
[](struct ShaderPassItem &a, struct ShaderPassItem &b) {
|
||||
if(a.priority == b.priority) {
|
||||
// Compare indexes if w is same.
|
||||
if(a.w == b.w) return a.index < b.index;
|
||||
return a.w < b.w;
|
||||
}
|
||||
return a.priority < b.priority;
|
||||
}
|
||||
);
|
||||
|
||||
// Now we've sorted everything! Let's actually start rendering.
|
||||
std::shared_ptr<Shader> boundShader;
|
||||
std::map<textureslot_t, Texture*> boundTextures;
|
||||
std::map<shaderbufferlocation_t, shaderbufferslot_t> boundBuffers;
|
||||
shaderbufferslot_t slot;
|
||||
|
||||
// TODO: This will be editable!
|
||||
renderTarget->bind();
|
||||
renderTarget->clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
|
||||
// Shader items
|
||||
itPassItem = shaderPassItems.begin();
|
||||
while(itPassItem != shaderPassItems.end()) {
|
||||
auto item = *itPassItem;
|
||||
|
||||
// Bind the program.
|
||||
if(boundShader != item.shader) {
|
||||
boundShader = item.shader;
|
||||
boundShader->bind();
|
||||
}
|
||||
|
||||
// Bind the textures to the slots
|
||||
auto itTextureSlot = item.textureSlots.begin();
|
||||
while(itTextureSlot != item.textureSlots.end()) {
|
||||
// Assert texture isn't null, just don't include it.
|
||||
assertNotNull(itTextureSlot->second, "Texture cannot be null (omit)");
|
||||
|
||||
if(boundTextures[itTextureSlot->first] != itTextureSlot->second) {
|
||||
itTextureSlot->second->bind(itTextureSlot->first);
|
||||
boundTextures[itTextureSlot->first] = itTextureSlot->second;
|
||||
}
|
||||
++itTextureSlot;
|
||||
}
|
||||
|
||||
// Bind the buffers to their slots
|
||||
slot = 0;
|
||||
auto itBufferSlot = item.parameterBuffers.begin();
|
||||
while(itBufferSlot != item.parameterBuffers.end()) {
|
||||
auto location = itBufferSlot->first;
|
||||
auto buff = itBufferSlot->second;
|
||||
boundBuffers[itBufferSlot->first] = slot;
|
||||
buff->bind(slot);
|
||||
slot++;
|
||||
++itBufferSlot;
|
||||
}
|
||||
|
||||
// Now set each of the parameters. Nothing exciting here.
|
||||
auto itColors = item.colorValues.begin();
|
||||
while(itColors != item.colorValues.end()) {
|
||||
item.shader->setColor(itColors->first, itColors->second);
|
||||
++itColors;
|
||||
}
|
||||
|
||||
auto itBool = item.boolValues.begin();
|
||||
while(itBool != item.boolValues.end()) {
|
||||
item.shader->setBoolean(itBool->first, itBool->second);
|
||||
++itBool;
|
||||
}
|
||||
|
||||
auto itMat = item.matrixValues.begin();
|
||||
while(itMat != item.matrixValues.end()) {
|
||||
item.shader->setMatrix(itMat->first, itMat->second);
|
||||
++itMat;
|
||||
}
|
||||
|
||||
auto itVec3 = item.vec3Values.begin();
|
||||
while(itVec3 != item.vec3Values.end()) {
|
||||
item.shader->setVector3(itVec3->first, itVec3->second);
|
||||
++itVec3;
|
||||
}
|
||||
|
||||
auto itText = item.textureValues.begin();
|
||||
while(itText != item.textureValues.end()) {
|
||||
item.shader->setTexture(itText->first, itText->second);
|
||||
++itText;
|
||||
}
|
||||
|
||||
auto itBuffer = item.parameterBuffers.begin();
|
||||
while(itBuffer != item.parameterBuffers.end()) {
|
||||
item.shader->setParameterBuffer(
|
||||
itBuffer->first, boundBuffers[itBuffer->first]
|
||||
);
|
||||
++itBuffer;
|
||||
}
|
||||
|
||||
auto itFloat = item.floatValues.begin();
|
||||
while(itFloat != item.floatValues.end()) {
|
||||
item.shader->setFloat(itFloat->first, itFloat->second);
|
||||
++itFloat;
|
||||
}
|
||||
|
||||
// Set Render flags
|
||||
rm->setRenderFlags(item.renderFlags);
|
||||
|
||||
// Thank god that's done, now just draw the damn mesh.
|
||||
item.mesh->draw(item.drawMode, item.start, item.count);
|
||||
++itPassItem;
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/IRenderManager.hpp"
|
||||
#include "display/shader/ShaderPass.hpp"
|
||||
#include "scene/components/display/IRenderable.hpp"
|
||||
#include "display/shader/buffers/RenderPipelineShaderBuffer.hpp"
|
||||
#include "scene/components/display/Camera.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderManager;
|
||||
|
||||
class RenderPipeline : public std::enable_shared_from_this<RenderPipeline> {
|
||||
private:
|
||||
int_fast16_t renderId = -1;
|
||||
|
||||
public:
|
||||
std::weak_ptr<RenderManager> renderManager;
|
||||
RenderPipelineShaderBuffer shaderBuffer;
|
||||
|
||||
/**
|
||||
* Constructs a new RenderPipeline. Render Pipelines are my attempt to
|
||||
* create both a flexible, but standard way to allow the individual games
|
||||
* to decide how they want to render the common scene-item models.
|
||||
*/
|
||||
RenderPipeline();
|
||||
|
||||
/**
|
||||
* Initialize the render pipeline.
|
||||
*
|
||||
* @param renderManager Parent render manager this pipeline belongs to.
|
||||
*/
|
||||
virtual void init(const std::weak_ptr<RenderManager> renderManager);
|
||||
|
||||
/**
|
||||
* Renders the games' currently active scene, and all of its' cameras.
|
||||
*/
|
||||
virtual void render();
|
||||
|
||||
/**
|
||||
* Render a specific scene, usually just called for the currently active
|
||||
* scene, but in future this could include sub-scenes.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
*/
|
||||
virtual void renderScene(const std::shared_ptr<Scene> scene);
|
||||
|
||||
/**
|
||||
* Render a specific camera on a specific scene.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
* @param camera Camera within the scene to render.
|
||||
*/
|
||||
virtual void renderSceneCamera(
|
||||
const std::shared_ptr<Scene> scene,
|
||||
const std::shared_ptr<Camera> camera
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleanup a render pipeline that has been initialized.
|
||||
*/
|
||||
virtual ~RenderPipeline();
|
||||
};
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/flag.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "state/StateEvent.hpp"
|
||||
|
||||
#define RENDER_TARGET_CLEAR_FLAG_COLOR FLAG_DEFINE(0)
|
||||
#define RENDER_TARGET_CLEAR_FLAG_DEPTH FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
class RenderTarget {
|
||||
public:
|
||||
StateEvent<
|
||||
RenderTarget&,
|
||||
const float_t,
|
||||
const float_t
|
||||
> eventRenderTargetResized;
|
||||
|
||||
/**
|
||||
* Return the width of the render target.
|
||||
*
|
||||
* @return The width of the render target.
|
||||
*/
|
||||
virtual float_t getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Return the height of the render target.
|
||||
*
|
||||
* @return The height of the render target.
|
||||
*/
|
||||
virtual float_t getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Returns the scale (as in pixel density) of the render target. This is
|
||||
* typically 1.0f, but on high DPI displays this may be 2.0f or higher.
|
||||
*
|
||||
* @return The scale of the render target.
|
||||
*/
|
||||
virtual float_t getScale() = 0;
|
||||
|
||||
/**
|
||||
* Sets the clear color of the render target when the clear method for
|
||||
* the color buffer is requested.
|
||||
*
|
||||
* @param color Color to use for the clear operation.
|
||||
*/
|
||||
virtual void setClearColor(const struct Color color) = 0;
|
||||
|
||||
/**
|
||||
* Request the existing data in the render target to be cleared out. We
|
||||
* typically assume the render target can support multiple buffer types,
|
||||
* so you can opt to only clear certain buffer types.
|
||||
*
|
||||
* @param clearFlags Flags to request what is going to be cleared.
|
||||
*/
|
||||
virtual void clear(const flag8_t clearFlags) = 0;
|
||||
|
||||
/**
|
||||
* Bind the render target for rendering to. The proceeding render requests
|
||||
* will want to render to this render target directly. In future I may
|
||||
* see if we can have multiple render targets bound at once to make this
|
||||
* operation perform faster.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
};
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Tileset.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
struct Tile Tileset::getTile(const int32_t tile) {
|
||||
assertTrue(tile >= 0, "Tile must be greater than or equal to 0");
|
||||
assertTrue(tile < this->tiles.size(), "Tile is out of bounds");
|
||||
return this->tiles[tile];
|
||||
}
|
||||
|
||||
TilesetGrid::TilesetGrid() {
|
||||
|
||||
}
|
||||
|
||||
TilesetGrid::TilesetGrid(
|
||||
Texture &texture,
|
||||
const int32_t columns,
|
||||
const int32_t rows
|
||||
) : TilesetGrid(
|
||||
columns, rows,
|
||||
texture.getWidth(), texture.getHeight(),
|
||||
0, 0,
|
||||
0, 0
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
TilesetGrid::TilesetGrid(
|
||||
const int32_t columns,
|
||||
const int32_t rows,
|
||||
const int32_t w,
|
||||
const int32_t h,
|
||||
const int32_t gapX,
|
||||
const int32_t gapY,
|
||||
const int32_t borderX,
|
||||
const int32_t borderY
|
||||
) {
|
||||
assertTrue(columns >= 1, "Columns must be greater than or equal to 1");
|
||||
assertTrue(rows >= 1, "Rows must be greater than or equal to 1");
|
||||
assertTrue(w >= 1, "Width must be greater than or equal to 1");
|
||||
assertTrue(h >= 1, "Height must be greater than or equal to 1");
|
||||
assertTrue(gapX >= 0, "GapX must be greater than or equal to 0");
|
||||
assertTrue(gapY >= 0, "GapY must be greater than or equal to 0");
|
||||
assertTrue(borderX >= 0, "BorderX must be greater than or equal to 0");
|
||||
assertTrue(borderY >= 0, "BorderY must be greater than or equal to 0");
|
||||
assertTrue(w >= (columns + (gapX * columns) + borderX + borderX), "Width is too small");
|
||||
assertTrue(h >= (rows + (gapY * rows) + borderY + borderY), "Height is too small");
|
||||
|
||||
this->rows = rows;
|
||||
this->columns = columns;
|
||||
|
||||
// Calculate division sizes (pixels)
|
||||
this->divX = (w - (borderX * 2) - (gapX * (columns - 1))) / columns;
|
||||
this->divY = (h - (borderY * 2) - (gapY * (rows - 1))) / rows;
|
||||
|
||||
// Calculate the division sizes (units)
|
||||
const float_t tdivX = (float_t)this->divX / (float_t)w;
|
||||
const float_t tdivY = (float_t)this->divY / (float_t)h;
|
||||
|
||||
struct Tile tile;
|
||||
for(int32_t y = 0; y < rows; y++) {
|
||||
for(int32_t x = 0; x < columns; x++) {
|
||||
tile.uv0.x = (borderX + ((float_t)this->divX * x) + (gapX * x)) / w;
|
||||
tile.uv1.x = tile.uv0.x + tdivX;
|
||||
|
||||
tile.uv0.y = (borderY + ((float_t)this->divY * y) + (gapY * y)) / h;
|
||||
tile.uv1.y = tile.uv0.y + tdivY;
|
||||
this->tiles.push_back(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float_t TilesetGrid::getTileWidth(const int32_t tile) {
|
||||
return this->divX;
|
||||
}
|
||||
|
||||
float_t TilesetGrid::getTileHeight(const int32_t tile) {
|
||||
return this->divY;
|
||||
}
|
||||
|
||||
struct Tile TilesetGrid::getTileFromGrid(
|
||||
const int32_t column,
|
||||
const int32_t row
|
||||
) {
|
||||
assertTrue(row > 0 && row < this->rows, "Row is out of bounds");
|
||||
assertTrue(column > 0 && column < this->columns, "Column is out of bounds");
|
||||
return this->getTile(row + (column * this->rows));
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct Tile {
|
||||
glm::vec2 uv0;
|
||||
glm::vec2 uv1;
|
||||
};
|
||||
|
||||
struct Tileset {
|
||||
public:
|
||||
std::vector<struct Tile> tiles;
|
||||
|
||||
/**
|
||||
* Returns the tile at the given tile index.
|
||||
*
|
||||
* @param tile Tile index to get.
|
||||
* @return Tile at that index.
|
||||
*/
|
||||
struct Tile getTile(const int32_t tile);
|
||||
|
||||
/**
|
||||
* Returns the width of an individual tile.
|
||||
*
|
||||
* @param tile The tile to get the width of.
|
||||
* @return The tile width.
|
||||
*/
|
||||
virtual float_t getTileWidth(const int32_t tile) = 0;
|
||||
|
||||
/**
|
||||
* Returns the height of an individual tile.
|
||||
*
|
||||
* @param tile The tile to get the height of.
|
||||
* @return The tile height.
|
||||
*/
|
||||
virtual float_t getTileHeight(const int32_t tile) = 0;
|
||||
};
|
||||
|
||||
struct TilesetGrid : public Tileset{
|
||||
public:
|
||||
int32_t rows;
|
||||
int32_t columns;
|
||||
int32_t divX;
|
||||
int32_t divY;
|
||||
|
||||
/**
|
||||
* Constructs a new Tileset Grid.
|
||||
*/
|
||||
TilesetGrid();
|
||||
|
||||
/**
|
||||
* Constructs a new Tileset Grid from a texture.
|
||||
*
|
||||
* @param texture Texture to use.
|
||||
* @param columns Columns in the grid.
|
||||
* @param rows Rows in the grid.
|
||||
*/
|
||||
TilesetGrid(
|
||||
Texture &texture,
|
||||
const int32_t columns,
|
||||
const int32_t rows
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructs a new Tileset Grid.
|
||||
*
|
||||
* @param columns How many columns in the grid of tiles.
|
||||
* @param rows How many rows in the grid of tiles.
|
||||
* @param w Width of the grid.
|
||||
* @param h Height of te grid.
|
||||
* @param gapX Gap / Gutter between tiles.
|
||||
* @param gapY Gap / Gutter between tiles.
|
||||
* @param borderX Border at the edge of the grid before the first tiles.
|
||||
* @param borderY Border at the edge of the grid before the first tiles.
|
||||
*/
|
||||
TilesetGrid(
|
||||
const int32_t columns,
|
||||
const int32_t rows,
|
||||
const int32_t w,
|
||||
const int32_t h,
|
||||
const int32_t gapX,
|
||||
const int32_t gapY,
|
||||
const int32_t borderX,
|
||||
const int32_t borderY
|
||||
);
|
||||
|
||||
float_t getTileWidth(const int32_t tile) override;
|
||||
float_t getTileHeight(const int32_t tile) override;
|
||||
|
||||
/**
|
||||
* Returns the tile at a given grid position.
|
||||
*
|
||||
* @param column Column (0 indexed) to get the tile of.
|
||||
* @param row Row (0 indexed) to get the tile of.
|
||||
* @return Tile at this grid position.
|
||||
*/
|
||||
struct Tile getTileFromGrid(const int32_t column, const int32_t row);
|
||||
};
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
add_subdirectory(truetype)
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
TrueTypeFaceTexture.cpp
|
||||
)
|
@ -1,109 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TrueTypeFaceTexture.hpp"
|
||||
#include "util/memory.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TrueTypeFaceTexture::TrueTypeFaceTexture(
|
||||
const FT_Face face,
|
||||
const struct TrueTypeFaceTextureStyle style
|
||||
) :
|
||||
face(face),
|
||||
style(style)
|
||||
{
|
||||
assertTrue(style.fontSize < 256, "Font size cannot be greater than 256");
|
||||
|
||||
// Set freetype font size prior to baking.
|
||||
if(FT_Set_Pixel_Sizes(face, 0, style.fontSize)) {
|
||||
assertUnreachable("Failed to set font size");
|
||||
}
|
||||
|
||||
size_t w = 0, h = 0;
|
||||
FT_ULong c;
|
||||
|
||||
// First pass, determine the textures' dimensions.
|
||||
for(c = TRUE_TYPE_CHAR_BEGIN; c < TRUE_TYPE_CHAR_END; c++) {
|
||||
// Load the character
|
||||
auto ret = FT_Load_Char(face, c, ~FT_LOAD_RENDER);
|
||||
if(ret) {
|
||||
assertUnreachable("Failed to load character (0)");
|
||||
}
|
||||
|
||||
if(face->glyph->bitmap.width == 0 || face->glyph->bitmap.rows == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Update the width and height
|
||||
w = mathMax<size_t>(w, face->glyph->bitmap.width);
|
||||
h += face->glyph->bitmap.rows;
|
||||
}
|
||||
|
||||
assertTrue(w > 0, "Width cannot be less than or equal to 0");
|
||||
assertTrue(h > 0, "Height cannot be less than or equal to 0");
|
||||
|
||||
// Now buffer pixels to the texture
|
||||
float_t y = 0;
|
||||
|
||||
// I'd love to just buffer straight to the GPU, but it seems that is a bit
|
||||
// unstable right now.
|
||||
uint8_t *buffer = (uint8_t *)memoryAllocateEmpty(w * h, sizeof(uint8_t));
|
||||
|
||||
size_t offset = 0;
|
||||
for(c = TRUE_TYPE_CHAR_BEGIN; c < TRUE_TYPE_CHAR_END; c++) {
|
||||
// Load the character
|
||||
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
|
||||
assertUnreachable("Failed to load character (1)");
|
||||
}
|
||||
|
||||
// Store the character information
|
||||
const struct TrueTypeCharacter info = {
|
||||
.advanceX = (float_t)(face->glyph->advance.x >> 6),
|
||||
.advanceY = (float_t)(face->glyph->advance.y >> 6),
|
||||
.bitmapSize = glm::vec2(
|
||||
face->glyph->bitmap.width,
|
||||
face->glyph->bitmap.rows
|
||||
),
|
||||
.bitmapPosition = glm::vec2(
|
||||
face->glyph->bitmap_left,
|
||||
-face->glyph->bitmap_top
|
||||
),
|
||||
.textureY = y
|
||||
};
|
||||
this->characterData[c] = info;
|
||||
|
||||
// Buffer the pixels, oh dear GOD there has to be a more efficient way.
|
||||
for(int32_t i = 0; i < face->glyph->bitmap.rows; i++) {
|
||||
memoryCopy(
|
||||
(void *)(face->glyph->bitmap.buffer + (i * face->glyph->bitmap.width)),
|
||||
(void *)(buffer + offset),
|
||||
face->glyph->bitmap.width * sizeof(uint8_t)
|
||||
);
|
||||
offset += w * sizeof(uint8_t);
|
||||
assertTrue(offset <= (w * h * sizeof(uint8_t)), "Buffer overflow");
|
||||
}
|
||||
y += face->glyph->bitmap.rows;
|
||||
}
|
||||
|
||||
this->texture.setSize(
|
||||
w, h,
|
||||
TEXTURE_FORMAT_R,
|
||||
TEXTURE_DATA_FORMAT_UNSIGNED_BYTE
|
||||
);
|
||||
this->texture.buffer(buffer);
|
||||
memoryFree(buffer);
|
||||
}
|
||||
|
||||
struct TrueTypeCharacter TrueTypeFaceTexture::getCharacterData(
|
||||
const FT_ULong c
|
||||
) {
|
||||
return this->characterData[c];
|
||||
}
|
||||
|
||||
TrueTypeFaceTexture::~TrueTypeFaceTexture() {
|
||||
FT_Done_Face(this->face);
|
||||
}
|
@ -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 <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include "util/flag.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
#define TRUE_TYPE_CHAR_BEGIN 0x00
|
||||
#define TRUE_TYPE_CHAR_END 0xFF
|
||||
|
||||
#define TRUE_TYPE_VARIANT_BOLD FLAG_DEFINE(0)
|
||||
#define TRUE_TYPE_VARIANT_ITALICS FLAG_DEFINE(1)
|
||||
|
||||
#define TRUE_TYPE_DECORATION_STRIKETHROUGH FLAG_DEFINE(0)
|
||||
#define TRUE_TYPE_DECORATION_UNDERLINE FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
class TrueTypeAsset;
|
||||
|
||||
struct TrueTypeCharacter {
|
||||
float_t advanceX;
|
||||
float_t advanceY;
|
||||
glm::vec2 bitmapSize;
|
||||
glm::vec2 bitmapPosition;
|
||||
float_t textureY;
|
||||
};
|
||||
|
||||
struct TrueTypeFaceTextureStyle {
|
||||
uint32_t fontSize;
|
||||
flag_t style;
|
||||
|
||||
/**
|
||||
* Overload for the less than operator.
|
||||
*
|
||||
* @param r Right hand side of the operator.
|
||||
* @return True if the left hand side is less than the right hand side.
|
||||
*/
|
||||
bool operator < (const struct TrueTypeFaceTextureStyle& r) const {
|
||||
return std::tie(fontSize, style) < std::tie(r.fontSize, r.style);
|
||||
}
|
||||
};
|
||||
|
||||
class TrueTypeFaceTexture {
|
||||
public:
|
||||
const FT_Face face;
|
||||
const struct TrueTypeFaceTextureStyle style;
|
||||
std::map<FT_ULong, struct TrueTypeCharacter> characterData;
|
||||
Texture texture;
|
||||
|
||||
/**
|
||||
* Construct a new New True Type Face Texture object
|
||||
*
|
||||
* @param face The freetype face object.
|
||||
* @param style Style that this font has, used for locking.
|
||||
*/
|
||||
TrueTypeFaceTexture(
|
||||
const FT_Face face,
|
||||
const struct TrueTypeFaceTextureStyle style
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the character data for the given character.
|
||||
*
|
||||
* @param c Character to get data for.
|
||||
* @return The Character data for the given character.
|
||||
*/
|
||||
struct TrueTypeCharacter getCharacterData(const FT_ULong c);
|
||||
|
||||
/**
|
||||
* Destroys this true type face texture.
|
||||
*/
|
||||
virtual ~TrueTypeFaceTexture();
|
||||
|
||||
friend class TrueTypeAsset;
|
||||
};
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
CapsuleMesh.cpp
|
||||
CubeMesh.cpp
|
||||
TriangleMesh.cpp
|
||||
QuadMesh.cpp
|
||||
SphereMesh.cpp
|
||||
)
|
@ -1,97 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "CapsuleMesh.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void CapsuleMesh::calculateRing(
|
||||
const int32_t segments,
|
||||
const float_t height,
|
||||
const float_t radius,
|
||||
const float_t dr,
|
||||
const float_t y,
|
||||
const float_t dy,
|
||||
std::vector<glm::vec3> &positions
|
||||
) {
|
||||
float_t segIncr = 1.0f / (float_t)(segments - 1);
|
||||
for(int32_t s = 0; s < segments; s++ ) {
|
||||
float_t x = cosf(MATH_PI * 2 * s * segIncr) * dr;
|
||||
float_t z = sinf(MATH_PI * 2 * s * segIncr) * dr;
|
||||
positions.emplace_back(glm::vec3(radius * x, radius * y + height * dy, radius * z ));
|
||||
}
|
||||
}
|
||||
|
||||
void CapsuleMesh::create(
|
||||
Mesh &mesh,
|
||||
const float_t radius,
|
||||
const float_t height
|
||||
) {
|
||||
std::vector<glm::vec3> positions;
|
||||
std::vector<meshindice_t> indices;
|
||||
|
||||
const int32_t slices = 12;
|
||||
const int32_t segments = 12;
|
||||
const int32_t ringsBody = slices + 1;
|
||||
const int32_t ringsTotal = slices + ringsBody;
|
||||
|
||||
positions.reserve(segments * ringsTotal);
|
||||
indices.reserve((segments - 1) * (ringsTotal - 1) * 6);
|
||||
|
||||
const float_t bodyIncr = 1.0f / (float_t)(ringsBody - 1);
|
||||
const float_t ringIncr = 1.0f / (float_t)(slices - 1);
|
||||
for(int32_t r = 0; r < slices / 2; r++) {
|
||||
calculateRing(
|
||||
segments,
|
||||
height,
|
||||
radius,
|
||||
sinf(MATH_PI * r * ringIncr),
|
||||
sinf(MATH_PI * (r * ringIncr - 0.5f)),
|
||||
-0.5f,
|
||||
positions
|
||||
);
|
||||
}
|
||||
|
||||
for(int32_t r = 0; r < ringsBody; r++ ) {
|
||||
calculateRing(
|
||||
segments,
|
||||
height,
|
||||
radius,
|
||||
1.0f,
|
||||
0.0f,
|
||||
r * bodyIncr - 0.5f,
|
||||
positions
|
||||
);
|
||||
}
|
||||
|
||||
for(int32_t r = slices / 2; r < slices; r++) {
|
||||
calculateRing(
|
||||
segments,
|
||||
height,
|
||||
radius,
|
||||
sinf(MATH_PI * r * ringIncr),
|
||||
sinf(MATH_PI * (r * ringIncr - 0.5f)),
|
||||
0.5f,
|
||||
positions
|
||||
);
|
||||
}
|
||||
|
||||
for(int32_t r = 0; r < ringsTotal - 1; r++ ) {
|
||||
for(int32_t s = 0; s < segments - 1; s++ ) {
|
||||
indices.push_back( (uint32_t)(r * segments + ( s + 1 )) );
|
||||
indices.push_back( (uint32_t)(r * segments + ( s + 0 )) );
|
||||
indices.push_back( (uint32_t)(( r + 1 ) * segments + ( s + 1 )) );
|
||||
|
||||
indices.push_back( (uint32_t)(( r + 1 ) * segments + ( s + 0 )) );
|
||||
indices.push_back( (uint32_t)(( r + 1 ) * segments + ( s + 1 )) );
|
||||
indices.push_back( (uint32_t)(r * segments + s) );
|
||||
}
|
||||
}
|
||||
|
||||
mesh.createBuffers(positions.size(), indices.size());
|
||||
mesh.bufferPositions(0, positions.data(), positions.size());
|
||||
mesh.bufferIndices(0, indices.data(), indices.size());
|
||||
}
|
@ -1,47 +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 CapsuleMesh {
|
||||
protected:
|
||||
/**
|
||||
* Calculates a ring of vertices within a capsule.
|
||||
*
|
||||
* @param segments Count of segments in the ring.
|
||||
* @param height Height of the ring.
|
||||
* @param radius Radius of the ring.
|
||||
* @param dr The delta radius of the ring.
|
||||
* @param y The y position of the ring.
|
||||
* @param dy The delta y position of the ring.
|
||||
* @param positions The positions vector to push the positions to.
|
||||
*/
|
||||
static void calculateRing(
|
||||
const int32_t segments,
|
||||
const float_t height,
|
||||
const float_t radius,
|
||||
const float_t dr,
|
||||
const float_t y,
|
||||
const float_t dy,
|
||||
std::vector<glm::vec3> &positions
|
||||
);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a capsule mesh.
|
||||
*
|
||||
* @param mesh Mesh to instanciate.
|
||||
* @param radius Radius of the capsule.
|
||||
* @param height Height of the capsule.
|
||||
*/
|
||||
static void create(
|
||||
Mesh &mesh,
|
||||
const float_t radius,
|
||||
const float_t height
|
||||
);
|
||||
};
|
||||
}
|
@ -1,70 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "CubeMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void CubeMesh::buffer(
|
||||
Mesh &mesh,
|
||||
const glm::vec3 pos,
|
||||
const glm::vec3 size,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
) {
|
||||
glm::vec3 positions[CUBE_VERTICE_COUNT] = {
|
||||
pos,
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z),
|
||||
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
|
||||
|
||||
glm::vec3(pos.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
|
||||
pos + size
|
||||
};
|
||||
|
||||
glm::vec2 coordinates[CUBE_VERTICE_COUNT] = {
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1),
|
||||
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1)
|
||||
};
|
||||
|
||||
meshindice_t indices[CUBE_INDICE_COUNT] = {
|
||||
// Back
|
||||
verticeStart, verticeStart + 1, verticeStart + 3,
|
||||
verticeStart, verticeStart + 2, verticeStart + 3,
|
||||
|
||||
// Right
|
||||
verticeStart + 1, verticeStart + 5, verticeStart + 7,
|
||||
verticeStart + 1, verticeStart + 3, verticeStart + 7,
|
||||
|
||||
// Left
|
||||
verticeStart + 4, verticeStart, verticeStart + 2,
|
||||
verticeStart + 4, verticeStart + 6, verticeStart + 2,
|
||||
|
||||
// Front
|
||||
verticeStart + 5, verticeStart + 4, verticeStart + 6,
|
||||
verticeStart + 5, verticeStart + 7, verticeStart + 6,
|
||||
|
||||
// Top
|
||||
verticeStart + 7, verticeStart + 2, verticeStart + 6,
|
||||
verticeStart + 7, verticeStart + 3, verticeStart + 2,
|
||||
|
||||
// Bottom
|
||||
verticeStart + 1, verticeStart, verticeStart + 4,
|
||||
verticeStart + 1, verticeStart + 4, verticeStart + 5
|
||||
};
|
||||
|
||||
mesh.bufferPositions(verticeStart, positions, CUBE_VERTICE_COUNT);
|
||||
mesh.bufferCoordinates(verticeStart, coordinates, CUBE_VERTICE_COUNT);
|
||||
mesh.bufferIndices(indiceStart, indices, CUBE_INDICE_COUNT);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
#define CUBE_VERTICE_COUNT 8
|
||||
#define CUBE_INDICE_COUNT 36
|
||||
|
||||
namespace Dawn {
|
||||
class CubeMesh {
|
||||
public:
|
||||
/**
|
||||
* Buffers cube mesh vertices onto a mesh.
|
||||
*
|
||||
* @param mesh Mesh to buffer onto.
|
||||
* @param pos Position of the cube.
|
||||
* @param size Size of the cube.
|
||||
* @param verticeStart Starting vertice index.
|
||||
* @param indiceStart Starting indice index.
|
||||
*/
|
||||
static void buffer(
|
||||
Mesh &mesh,
|
||||
const glm::vec3 pos,
|
||||
const glm::vec3 size,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
);
|
||||
};
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void QuadMesh::bufferQuadMeshWithZ(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const float_t z,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
) {
|
||||
glm::vec3 positions[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec3(xy0, z),
|
||||
glm::vec3(xy1.x, xy0.y, z),
|
||||
glm::vec3(xy0.x, xy1.y, z),
|
||||
glm::vec3(xy1, z)
|
||||
};
|
||||
glm::vec2 coordinates[QUAD_VERTICE_COUNT] = {
|
||||
uv0, glm::vec2(uv1.x, uv0.y),
|
||||
glm::vec2(uv0.x, uv1.y), uv1
|
||||
};
|
||||
meshindice_t indices[QUAD_INDICE_COUNT] = {
|
||||
verticeStart, verticeStart + 1, verticeStart + 2,
|
||||
verticeStart + 1, verticeStart + 2, verticeStart + 3
|
||||
};
|
||||
|
||||
mesh.bufferPositions(verticeStart, positions, QUAD_VERTICE_COUNT);
|
||||
mesh.bufferCoordinates(verticeStart, coordinates, QUAD_VERTICE_COUNT);
|
||||
mesh.bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferQuadMesh(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
) {
|
||||
QuadMesh::bufferQuadMeshWithZ(
|
||||
mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart
|
||||
);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferCoordinates(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 uv1,
|
||||
const int32_t verticeStart
|
||||
) {
|
||||
glm::vec2 coordinates[QUAD_VERTICE_COUNT] = {
|
||||
uv0, glm::vec2(uv1.x, uv0.y),
|
||||
glm::vec2(uv0.x, uv1.y), uv1
|
||||
};
|
||||
mesh.bufferCoordinates(verticeStart, coordinates, QUAD_VERTICE_COUNT);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferPositions(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 xy1,
|
||||
const int32_t verticeStart
|
||||
) {
|
||||
glm::vec3 positions[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec3(xy0, 0),
|
||||
glm::vec3(xy1.x, xy0.y, 0),
|
||||
glm::vec3(xy0.x, xy1.y, 0),
|
||||
glm::vec3(xy1, 0)
|
||||
};
|
||||
mesh.bufferPositions(verticeStart, positions, QUAD_VERTICE_COUNT);
|
||||
}
|
||||
|
||||
void QuadMesh::initQuadMesh(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const float_t z
|
||||
) {
|
||||
mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
|
||||
QuadMesh::bufferQuadMeshWithZ(mesh, xy0, uv0, xy1, uv1, z, 0, 0);
|
||||
}
|
@ -1,109 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
#define QUAD_VERTICE_COUNT 4
|
||||
#define QUAD_INDICE_COUNT 6
|
||||
#define QUAD_INDICE_PER_QUAD 2
|
||||
|
||||
namespace Dawn {
|
||||
class QuadMesh {
|
||||
public:
|
||||
/**
|
||||
* Buffers the vertices of a quad onto a primitive.
|
||||
*
|
||||
* @param mesh The primitive to buffer to.
|
||||
* @param xy0 The lower X and Y coordinate.
|
||||
* @param uv0 The lower Xand Y texture coordinate.
|
||||
* @param xy1 The higher X and Y coordinate.
|
||||
* @param uv1 The higher X and Y texture coordinate.
|
||||
* @param z The Z position of the coordinates.
|
||||
* @param verticeStart Start vertice to buffer to.
|
||||
* @param indiceStart Start indice to buffer to.
|
||||
*/
|
||||
static void bufferQuadMeshWithZ(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const float_t z,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Buffers the vertices of a quad onto a primitive.
|
||||
*
|
||||
* @param mesh The primitive to buffer to.
|
||||
* @param xy0 The lower X and Y coordinate.
|
||||
* @param uv0 The lower Xand Y texture coordinate.
|
||||
* @param xy1 The higher X and Y coordinate.
|
||||
* @param uv1 The higher X and Y texture coordinate.
|
||||
* @param verticeStart Start vertice to buffer to.
|
||||
* @param indiceStart Start indice to buffer to.
|
||||
*/
|
||||
static void bufferQuadMesh(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Buffers texture coordinates on to an already initialized quad mesh.
|
||||
*
|
||||
* @param mesh Mesh to buffer the texture coordinates on to.
|
||||
* @param uv0 Lower X and Y coordinates.
|
||||
* @param uv1 Upper X and Y coordinates.
|
||||
* @param verticeStart Start vertice to buffer in to.
|
||||
*/
|
||||
static void bufferCoordinates(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 uv1,
|
||||
const int32_t verticeStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Buffers the positions of a quad onto a primitive.
|
||||
*
|
||||
* @param mesh The primitive to buffer to.
|
||||
* @param xy0 The lower X and Y coordinate.
|
||||
* @param xy1 The higher X and Y coordinate.
|
||||
* @param verticeStart Start vertice to buffer to.
|
||||
*/
|
||||
static void bufferPositions(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 xy1,
|
||||
const int32_t verticeStart
|
||||
);
|
||||
|
||||
/**
|
||||
* Initializes a mesh to be a single quad.
|
||||
*
|
||||
* @param mesh The primitive to buffer to.
|
||||
* @param xy0 The lower X and Y coordinate.
|
||||
* @param uv0 The lower Xand Y texture coordinate.
|
||||
* @param xy1 The higher X and Y coordinate.
|
||||
* @param uv1 The higher X and Y texture coordinate.
|
||||
* @param z The Z position of the coordinates.
|
||||
*/
|
||||
static void initQuadMesh(
|
||||
Mesh &mesh,
|
||||
const glm::vec2 xy0,
|
||||
const glm::vec2 uv0,
|
||||
const glm::vec2 xy1,
|
||||
const glm::vec2 uv1,
|
||||
const float_t z
|
||||
);
|
||||
};
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SphereMesh.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void SphereMesh::createSphere(
|
||||
Mesh &mesh,
|
||||
const float_t radius,
|
||||
const int32_t slices,
|
||||
const int32_t stacks
|
||||
) {
|
||||
std::vector<glm::vec3> positions;
|
||||
|
||||
// Create vertices
|
||||
int32_t c = 0;
|
||||
for (int32_t i = 0; i <= stacks; i++) {
|
||||
float_t phi = MATH_PI * i / stacks;
|
||||
float_t cosPhi = cos(phi);
|
||||
float_t sinPhi = sin(phi);
|
||||
|
||||
for (int32_t j = 0; j <= slices; j++) {
|
||||
float_t theta = 2 * MATH_PI * j / slices;
|
||||
float_t cosTheta = cos(theta);
|
||||
float_t sinTheta = sin(theta);
|
||||
|
||||
glm::vec3 v;
|
||||
v.x = radius * sinPhi * cosTheta;
|
||||
v.y = radius * sinPhi * sinTheta;
|
||||
v.z = radius * cosPhi;
|
||||
|
||||
positions.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
// Create indices
|
||||
std::vector<meshindice_t> indices;
|
||||
for (int32_t i = 0; i < stacks; i++) {
|
||||
for (int32_t j = 0; j < slices; j++) {
|
||||
meshindice_t p1 = i * (slices + 1) + j;
|
||||
meshindice_t p2 = p1 + slices + 1;
|
||||
|
||||
indices.push_back(p1);
|
||||
indices.push_back(p2);
|
||||
indices.push_back(p1 + 1);
|
||||
|
||||
indices.push_back(p1 + 1);
|
||||
indices.push_back(p2);
|
||||
indices.push_back(p2 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
mesh.createBuffers(positions.size(), indices.size());
|
||||
mesh.bufferPositions(0, positions.data(), positions.size());
|
||||
mesh.bufferIndices(0, indices.data(), indices.size());
|
||||
}
|
@ -1,27 +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 SphereMesh {
|
||||
public:
|
||||
/**
|
||||
* Creates a sphere mesh.
|
||||
*
|
||||
* @param mesh Mesh to instanciate.
|
||||
* @param radius Radius of the sphere.
|
||||
* @param slices How many horizontal slices to make.
|
||||
* @param stacks How many vertical stacks to make.
|
||||
*/
|
||||
static void createSphere(
|
||||
Mesh &mesh,
|
||||
const float_t radius,
|
||||
const int32_t slices,
|
||||
const int32_t stacks
|
||||
);
|
||||
};
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/mesh/TriangleMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void TriangleMesh::createTriangleMesh(Mesh &mesh) {
|
||||
glm::vec3 positions[3] = {
|
||||
glm::vec3(-0.5f, -0.5f, 0),
|
||||
glm::vec3(0.5f, -0.5f, 0),
|
||||
glm::vec3(0, 0.5f, 0)
|
||||
};
|
||||
|
||||
glm::vec2 coordinates[3] = {
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 0)
|
||||
};
|
||||
|
||||
meshindice_t indices[3] = {
|
||||
0, 1, 2
|
||||
};
|
||||
|
||||
mesh.createBuffers(3, 3);
|
||||
mesh.bufferPositions(0, positions, 3);
|
||||
mesh.bufferCoordinates(0, coordinates, 3);
|
||||
mesh.bufferIndices(0, indices, 3);
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
// Copyright (c) 2022 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 TriangleMesh {
|
||||
public:
|
||||
/**
|
||||
* Initializes a mesh to hold a single triangle.
|
||||
*
|
||||
* @param mesh Mesh to initialize as a triangle.
|
||||
*/
|
||||
static void createTriangleMesh(Mesh &mesh);
|
||||
};
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
ShaderManager.cpp
|
||||
)
|
@ -1,112 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Texture.hpp"
|
||||
#include "display/shader/ShaderParameterBuffer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename T>
|
||||
class IShader {
|
||||
public:
|
||||
int32_t shaderId = -1;
|
||||
int_fast16_t renderId = 0;
|
||||
|
||||
/**
|
||||
* Compile all programs for this shader.
|
||||
*/
|
||||
virtual void compile() = 0;
|
||||
|
||||
/**
|
||||
* Attaches the supplied shader as the current shader.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Binds a shader buffer to a specific slot.
|
||||
*
|
||||
* @param slot Slot to bind the buffer to.
|
||||
* @param buffer Buffer to bind.
|
||||
*/
|
||||
template<typename J>
|
||||
void setParameterBuffer(
|
||||
const shaderbufferslot_t slot,
|
||||
const ShaderParameterBuffer<J> &buffer
|
||||
);
|
||||
|
||||
/**
|
||||
* Set's a specific shader parameter to a matrix.
|
||||
*
|
||||
* @param parameter parameter on the shader to set.
|
||||
* @param matrix Matrix to apply.
|
||||
*/
|
||||
virtual void setMatrix(
|
||||
const T parameter,
|
||||
const glm::mat4 matrix
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a boolean to a shader.
|
||||
*
|
||||
* @param parameter parameter to set.
|
||||
* @param value Value to set.
|
||||
*/
|
||||
virtual void setBoolean(
|
||||
const T parameter,
|
||||
const bool_t value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Set a color on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the color to.
|
||||
* @param color Color to set.
|
||||
*/
|
||||
virtual void setColor(
|
||||
const T parameter,
|
||||
const struct Color color
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Set a 3D vector on to the shader.
|
||||
*
|
||||
* @param parameter parameter to set the vector to.
|
||||
* @param vector Vector to set.
|
||||
*/
|
||||
virtual void setVector3(
|
||||
const T parameter,
|
||||
const glm::vec3 vector
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Attaches a texture to the currently bound shader.
|
||||
*
|
||||
* @param parameter parameter to set the texture on to.
|
||||
* @param texture Texture slot to bind to the parameter.
|
||||
*/
|
||||
virtual void setTexture(
|
||||
const T parameter,
|
||||
const textureslot_t texture
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Sets a floating point value to the shader.
|
||||
*
|
||||
* @param parameter Paramater to set the float ont o.
|
||||
* @param Float to bind.
|
||||
*/
|
||||
virtual void setFloat(
|
||||
const T parameter,
|
||||
const float_t value
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Destroys/Cleans up the shader.
|
||||
*/
|
||||
virtual ~IShader() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename L>
|
||||
class IShaderParameterBuffer {
|
||||
public:
|
||||
/**
|
||||
* Initializes this shader parameter buffer.
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Bind this shader buffer to the supplied location.
|
||||
*
|
||||
* @param location Location to bind this buffer to.
|
||||
*/
|
||||
virtual void bind(const L location) = 0;
|
||||
};
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderManager::ShaderManager() {
|
||||
this->nextId = 0;
|
||||
this->nextLock = 0;
|
||||
}
|
||||
|
||||
ShaderManager::~ShaderManager() {
|
||||
}
|
@ -1,106 +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 {
|
||||
typedef int64_t shaderlock_t;
|
||||
typedef int16_t shaderid_t;
|
||||
|
||||
class ShaderManager {
|
||||
private:
|
||||
int32_t nextId;
|
||||
shaderlock_t nextLock;
|
||||
std::map<shaderid_t, std::shared_ptr<Shader>> shaders;
|
||||
std::map<shaderlock_t, shaderid_t> shaderLocks;
|
||||
std::map<shaderid_t, std::vector<shaderlock_t>> shaderLocksByShader;
|
||||
|
||||
/**
|
||||
* Returns the shader id for the given shader type, or -1 if it is not
|
||||
* loaded.
|
||||
*
|
||||
* @return The shader id for the shader, or -1 if it is not loaded.
|
||||
*/
|
||||
template<class T>
|
||||
shaderid_t getShaderId() {
|
||||
auto it = shaders.begin();
|
||||
while(it != shaders.end()) {
|
||||
auto asT = std::dynamic_pointer_cast<T>(it->second);
|
||||
if(asT != nullptr) return asT->shaderId;
|
||||
++it;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new shader manager.
|
||||
*/
|
||||
ShaderManager();
|
||||
|
||||
/**
|
||||
* Locks a shader of the given type. If the shader is not already loaded,
|
||||
* it will be loaded. If the shader is already loaded, it will be
|
||||
* returned.
|
||||
*
|
||||
* @return The shader lock for the shader of the given type.
|
||||
*/
|
||||
template<class T>
|
||||
shaderlock_t lockShader() {
|
||||
auto shaderId = this->getShaderId<T>();
|
||||
if(shaderId == -1) {
|
||||
auto shader = std::make_shared<T>();
|
||||
shader->compile();
|
||||
shader->shaderId = this->nextId++;
|
||||
this->shaders[shader->shaderId] = shader;
|
||||
shaderId = shader->shaderId;
|
||||
}
|
||||
|
||||
shaderlock_t lock = this->nextLock++;
|
||||
this->shaderLocks[lock] = shaderId;
|
||||
this->shaderLocksByShader[shaderId].push_back(lock);
|
||||
return lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shader for the given lock.
|
||||
*
|
||||
* @param lock The shader lock.
|
||||
* @return The shader for the given lock.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getShader(shaderlock_t lock) {
|
||||
auto shaderId = this->shaderLocks[lock];
|
||||
return std::static_pointer_cast<T>(this->shaders[shaderId]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Releases the shader for the given lock. This will unload any shader
|
||||
* that is no longer in use.
|
||||
*
|
||||
* @param lock Lock to release.
|
||||
*/
|
||||
template<class T>
|
||||
void releaseShader(shaderlock_t lock) {
|
||||
auto shaderId = this->shaderLocks[lock];
|
||||
this->shaderLocks.erase(lock);
|
||||
|
||||
auto& locks = this->shaderLocksByShader[shaderId];
|
||||
auto it = std::find(locks.begin(), locks.end(), lock);
|
||||
if(it != locks.end()) locks.erase(it);
|
||||
|
||||
if(locks.size() == 0) {
|
||||
this->shaderLocksByShader.erase(shaderId);
|
||||
this->shaders.erase(shaderId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the shader manager.
|
||||
*/
|
||||
~ShaderManager();
|
||||
};
|
||||
}
|
@ -1,37 +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"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ShaderPassItem;
|
||||
|
||||
struct ShaderPassItem {
|
||||
std::shared_ptr<Shader> shader;
|
||||
int32_t priority = 0;
|
||||
std::vector<struct ShaderPassItem>::iterator index;
|
||||
|
||||
Mesh *mesh;
|
||||
int32_t start = 0;
|
||||
int32_t count = -1;
|
||||
float_t w = 0;
|
||||
flag_t renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST;
|
||||
enum MeshDrawMode drawMode = MESH_DRAW_MODE_TRIANGLES;
|
||||
|
||||
// Parameters
|
||||
std::map<shaderparameter_t, struct Color> colorValues;
|
||||
std::map<shaderparameter_t, bool_t> boolValues;
|
||||
std::map<shaderparameter_t, glm::mat4> matrixValues;
|
||||
std::map<shaderparameter_t, glm::vec3> vec3Values;
|
||||
std::map<shaderparameter_t, textureslot_t> textureValues;
|
||||
std::map<shaderparameter_t, float_t> floatValues;
|
||||
std::map<shaderbufferlocation_t, IShaderParameterBuffer<shaderbufferslot_t>*> parameterBuffers;
|
||||
|
||||
// Textures
|
||||
std::map<textureslot_t, Texture*> textureSlots;
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user