Base refactor

This commit is contained in:
2023-11-14 09:16:48 -06:00
parent 214082d00f
commit 1817dcaf3a
410 changed files with 749 additions and 20823 deletions

View File

@ -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)

View File

@ -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 {};
}

View File

@ -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
}

View File

@ -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() {
}
};
}

View File

@ -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() {
}
};
}

View File

@ -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() {
}

View File

@ -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();
};
}

View File

@ -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;
};
}

View File

@ -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));
}

View File

@ -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);
};
}

View File

@ -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)

View File

@ -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
)

View File

@ -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);
}

View File

@ -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;
};
}

View File

@ -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
)

View File

@ -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());
}

View File

@ -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
);
};
}

View File

@ -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);
}

View File

@ -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
);
};
}

View File

@ -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);
}

View File

@ -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
);
};
}

View File

@ -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());
}

View File

@ -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
);
};
}

View File

@ -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);
}

View File

@ -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);
};
}

View File

@ -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
)

View File

@ -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() {
}
};
}

View File

@ -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;
};
}

View File

@ -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() {
}

View File

@ -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();
};
}

View File

@ -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;
};
}