GAME PROG
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -19,3 +19,6 @@
|
||||
[submodule "lib/libarchive"]
|
||||
path = lib/libarchive
|
||||
url = https://github.com/libarchive/libarchive
|
||||
[submodule "lib/boxer"]
|
||||
path = lib/boxer
|
||||
url = https://github.com/aaronmjacobs/Boxer
|
||||
|
@ -19,6 +19,9 @@ if(DAWN_BUILD_SYSTEM STREQUAL "linux")
|
||||
|
||||
add_subdirectory(freetype)
|
||||
|
||||
add_subdirectory(boxer)
|
||||
target_compile_definitions(Boxer PRIVATE UNICODE)
|
||||
|
||||
elseif(DAWN_BUILD_SYSTEM STREQUAL "vita")
|
||||
add_subdirectory(glm)
|
||||
|
||||
|
1
lib/boxer
Submodule
1
lib/boxer
Submodule
Submodule lib/boxer added at 65e79c38f1
@ -9,6 +9,7 @@ if(DAWN_BUILD_SYSTEM STREQUAL "linux")
|
||||
add_subdirectory(dawnglfw)
|
||||
add_subdirectory(dawnlinux)
|
||||
add_subdirectory(dawnopengl)
|
||||
add_subdirectory(dawnrpg)
|
||||
elseif(DAWN_BUILD_SYSTEM STREQUAL "vita")
|
||||
add_subdirectory(dawn)
|
||||
add_subdirectory(dawnvita)
|
||||
|
@ -22,6 +22,12 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(error)
|
||||
add_subdirectory(game)
|
||||
add_subdirectory(locale)
|
||||
add_subdirectory(scene)
|
||||
add_subdirectory(util)
|
||||
|
||||
# Textures
|
||||
# tool_texture(texture_test
|
||||
|
@ -6,8 +6,32 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
#include <cstdarg>
|
||||
|
||||
typedef char char_t;
|
||||
#define DAWN_GAME_NAME "Dawn"
|
||||
#define DAWN_GAME_NAME_U8 u8"Dawn"
|
||||
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <map>
|
||||
#include <array>
|
||||
#include <memory>
|
||||
#include <algorithm>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <float.h>
|
||||
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtx/matrix_decompose.hpp>
|
||||
|
||||
typedef char char_t;
|
||||
typedef char8_t u8char_t;
|
||||
typedef float float_t;
|
||||
typedef double double_t;
|
||||
typedef bool bool_t;
|
16
src/dawn/display/CMakeLists.txt
Normal file
16
src/dawn/display/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
||||
# 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
|
||||
Color.cpp
|
||||
RenderPipeline.cpp
|
||||
RenderManager.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(mesh)
|
||||
add_subdirectory(shader)
|
84
src/dawn/display/Color.cpp
Normal file
84
src/dawn/display/Color.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Color.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "util/string.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 {};
|
||||
}
|
89
src/dawn/display/Color.hpp
Normal file
89
src/dawn/display/Color.hpp
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ColorU8 {
|
||||
uint8_t r, g, b, a;
|
||||
};
|
||||
|
||||
struct Color final {
|
||||
/**
|
||||
* 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)
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
#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_YELLOW COLOR_DEF(1.0f, 1.0f, 0.0f, 1.0f)
|
||||
#define COLOR_CYAN COLOR_DEF(0.0f, 1.0f, 1.0f, 1.0f)
|
||||
#define COLOR_TRANSPARENT COLOR_WHITE_TRANSPARENT
|
||||
}
|
117
src/dawn/display/ITexture.hpp
Normal file
117
src/dawn/display/ITexture.hpp
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Color.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class TextureFormat {
|
||||
R = 1,
|
||||
RG = 2,
|
||||
RGB = 3,
|
||||
RGBA = 4
|
||||
};
|
||||
|
||||
enum class TextureWrapMode {
|
||||
REPEAT = 0,
|
||||
MIRRORED_REPEAT = 1,
|
||||
CLAMP_TO_EDGE = 2,
|
||||
CLAMP_TO_BORDER = 3
|
||||
};
|
||||
|
||||
enum class TextureFilterMode {
|
||||
NEAREST = 0,
|
||||
LINEAR = 1
|
||||
};
|
||||
|
||||
enum class TextureDataFormat {
|
||||
UNSIGNED_BYTE = sizeof(uint8_t),
|
||||
FLOAT = sizeof(float_t)
|
||||
};
|
||||
|
||||
class ITexture {
|
||||
public:
|
||||
enum TextureWrapMode wrapModeX = TextureWrapMode::REPEAT;
|
||||
enum TextureWrapMode wrapModeY = TextureWrapMode::REPEAT;
|
||||
enum TextureFilterMode filterModeMin = TextureFilterMode::NEAREST;
|
||||
enum TextureFilterMode filterModeMag = TextureFilterMode::NEAREST;
|
||||
enum TextureFilterMode mipMapFilterModeMin = TextureFilterMode::NEAREST;
|
||||
enum TextureFilterMode mipMapFilterModeMag = TextureFilterMode::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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
virtual void buffer(const struct ColorU8 pixels[]) = 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.
|
||||
*/
|
||||
virtual void buffer(const struct Color pixels[]) = 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.
|
||||
*/
|
||||
virtual void buffer(const uint8_t pixels[]) = 0;
|
||||
|
||||
/**
|
||||
* Binds the texture to the given slot (for use by the shaders).
|
||||
*
|
||||
* @param slot Slot to bind to.
|
||||
*/
|
||||
virtual void bind(const uint8_t slot) = 0;
|
||||
|
||||
/**
|
||||
* Disposes of the texture.
|
||||
*/
|
||||
virtual ~ITexture() {
|
||||
}
|
||||
};
|
||||
}
|
32
src/dawn/display/RenderManager.cpp
Normal file
32
src/dawn/display/RenderManager.cpp
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RenderManager.hpp"
|
||||
#include "game/Game.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderManager::RenderManager() :
|
||||
renderPipeline(),
|
||||
shaderManager()
|
||||
{
|
||||
}
|
||||
|
||||
void RenderManager::init(const Game &game) {
|
||||
backBuffer = std::make_shared<BackBuffer>();
|
||||
backBuffer->setClearColor(COLOR_CORNFLOWER_BLUE);
|
||||
}
|
||||
|
||||
void RenderManager::update(const Game &game) {
|
||||
backBuffer->bind();
|
||||
backBuffer->clear(RENDER_TARGET_CLEAR_COLOR | RENDER_TARGET_CLEAR_DEPTH);
|
||||
}
|
||||
|
||||
std::shared_ptr<BackBuffer> RenderManager::getBackBufferRenderTarget() {
|
||||
return backBuffer;
|
||||
}
|
||||
|
||||
RenderManager::~RenderManager() {
|
||||
}
|
@ -1,13 +1,56 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
#include "display/RenderPipeline.hpp"
|
||||
#include "display/shader/ShaderManager.hpp"
|
||||
#include "display/BackBuffer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Game;
|
||||
|
||||
class RenderManager {
|
||||
private:
|
||||
std::shared_ptr<BackBuffer> backBuffer = nullptr;
|
||||
|
||||
public:
|
||||
|
||||
}
|
||||
RenderPipeline renderPipeline;
|
||||
ShaderManager shaderManager;
|
||||
|
||||
/**
|
||||
* Creates a render manager.
|
||||
*/
|
||||
RenderManager();
|
||||
|
||||
/**
|
||||
* Initializes the render manager, called by the game during the initial
|
||||
* set up of the engine.
|
||||
*
|
||||
* @param game Game that requested the render manager to initialize.
|
||||
*/
|
||||
void init(const Game &game);
|
||||
|
||||
/**
|
||||
* Performs an update/tick of the render manager. This would be the game
|
||||
* asking the RenderManager to do the rendering.
|
||||
*/
|
||||
void update(const Game &game);
|
||||
|
||||
/**
|
||||
* Returns the back buffer render target. This is the render target that
|
||||
* is used to render to the screen.
|
||||
*
|
||||
* @return The back buffer render target.
|
||||
*/
|
||||
std::shared_ptr<BackBuffer> getBackBufferRenderTarget();
|
||||
|
||||
/**
|
||||
* Destroys the render manager.
|
||||
*/
|
||||
~RenderManager();
|
||||
};
|
||||
}
|
18
src/dawn/display/RenderPipeline.cpp
Normal file
18
src/dawn/display/RenderPipeline.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "error/assert.hpp"
|
||||
#include "RenderPipeline.hpp"
|
||||
#include "game/Game.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPipeline::RenderPipeline() {
|
||||
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
|
||||
}
|
22
src/dawn/display/RenderPipeline.hpp
Normal file
22
src/dawn/display/RenderPipeline.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderPipeline {
|
||||
public:
|
||||
/**
|
||||
* Creates a new RenderPipeline.
|
||||
*/
|
||||
RenderPipeline();
|
||||
|
||||
/**
|
||||
* Destroys the RenderPipeline.
|
||||
*/
|
||||
virtual ~RenderPipeline();
|
||||
};
|
||||
}
|
71
src/dawn/display/RenderTarget.hpp
Normal file
71
src/dawn/display/RenderTarget.hpp
Normal file
@ -0,0 +1,71 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "event/Event.hpp"
|
||||
|
||||
#define RENDER_TARGET_CLEAR_COLOR (1 << 0)
|
||||
#define RENDER_TARGET_CLEAR_DEPTH (1 << 1)
|
||||
|
||||
namespace Dawn {
|
||||
class RenderTarget {
|
||||
public:
|
||||
Event<float_t, float_t> onResize;
|
||||
|
||||
/**
|
||||
* 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 int32_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;
|
||||
|
||||
/**
|
||||
* Destroys the render target.
|
||||
*/
|
||||
virtual ~RenderTarget() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
11
src/dawn/display/mesh/CMakeLists.txt
Normal file
11
src/dawn/display/mesh/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
CubeMesh.cpp
|
||||
QuadMesh.cpp
|
||||
)
|
70
src/dawn/display/mesh/CubeMesh.cpp
Normal file
70
src/dawn/display/mesh/CubeMesh.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "CubeMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void CubeMesh::buffer(
|
||||
const std::shared_ptr<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)
|
||||
};
|
||||
|
||||
int32_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);
|
||||
}
|
30
src/dawn/display/mesh/CubeMesh.hpp
Normal file
30
src/dawn/display/mesh/CubeMesh.hpp
Normal file
@ -0,0 +1,30 @@
|
||||
// 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"
|
||||
|
||||
#define CUBE_VERTICE_COUNT 8
|
||||
#define CUBE_INDICE_COUNT 36
|
||||
|
||||
namespace Dawn {
|
||||
class CubeMesh {
|
||||
public:
|
||||
/**
|
||||
* Buffers cube mesh vertices and indices into the given mesh.
|
||||
*
|
||||
* @param size The size of the cube.
|
||||
* @param verticeStart The starting index of the vertices.
|
||||
* @param indiceStart The starting index of the indices.
|
||||
*/
|
||||
static void buffer(
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const glm::vec3 pos,
|
||||
const glm::vec3 size,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart
|
||||
);
|
||||
};
|
||||
}
|
102
src/dawn/display/mesh/IMesh.hpp
Normal file
102
src/dawn/display/mesh/IMesh.hpp
Normal file
@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum MeshDrawMode {
|
||||
TRIANGLES,
|
||||
TRIANGLE_STRIP,
|
||||
TRIANGLE_FAN,
|
||||
LINES,
|
||||
POINTS
|
||||
// LINE_STRIP,
|
||||
};
|
||||
|
||||
class IMesh {
|
||||
protected:
|
||||
/** How many vertices are in the mesh */
|
||||
int32_t verticeCount = -1;
|
||||
/** How many indices are in the mesh */
|
||||
int32_t indiceCount = -1;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create a new set of buffers for the mesh to use.
|
||||
*
|
||||
* @param verticeCount How many Vertices will this buffer support.
|
||||
* @param indiceCount How many Indices will this buffer support.
|
||||
*/
|
||||
virtual void createBuffers(
|
||||
const int32_t verticeCount,
|
||||
const int32_t indiceCount
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Cleanup the buffers on a given mesh. This is useful if you intend to
|
||||
* expand the count of vertices your mesh supports.
|
||||
*/
|
||||
virtual void disposeBuffers() = 0;
|
||||
|
||||
/**
|
||||
* Write vertice positions to the mesh.
|
||||
*
|
||||
* @param pos Position, within the buffer, to write to.
|
||||
* @param vertices Array of positions to write.
|
||||
* @param len How many positions are in the array.
|
||||
*/
|
||||
virtual void bufferPositions(
|
||||
const int32_t pos,
|
||||
const glm::vec3 positions[],
|
||||
const int32_t len
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Write vertice coordinates to the mesh.
|
||||
*
|
||||
* @param pos Position, within the buffer, to write to.
|
||||
* @param coordinates Array of coordinates to write.
|
||||
* @param len How many coordinates are in the array.
|
||||
*/
|
||||
virtual void bufferCoordinates(
|
||||
const int32_t pos,
|
||||
const glm::vec2 coordinates[],
|
||||
const int32_t len
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Write indices to the mesh.
|
||||
*
|
||||
* @param pos Position, within the buffer, to write to.
|
||||
* @param indices Array of indices to write.
|
||||
* @param len How many indices are in the array.
|
||||
*/
|
||||
virtual void bufferIndices(
|
||||
const int32_t pos,
|
||||
const int32_t indices[],
|
||||
const int32_t len
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Draw a primitive. Primitives are drawn by their indices.
|
||||
*
|
||||
* @param drawMode Which drawing mode to use to draw the primitive.
|
||||
* @param start Start indice (index) to draw.
|
||||
* @param count Count of indices to draw. Use -1 to draw all.
|
||||
*/
|
||||
virtual void draw(
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t start,
|
||||
const int32_t count
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Cleanup a previously initiated mesh.
|
||||
*/
|
||||
virtual ~IMesh() {
|
||||
}
|
||||
};
|
||||
}
|
72
src/dawn/display/mesh/QuadMesh.cpp
Normal file
72
src/dawn/display/mesh/QuadMesh.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void QuadMesh::buffer(
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const glm::vec4 positions,
|
||||
const glm::vec4 coordinates,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart,
|
||||
const float_t depth
|
||||
) {
|
||||
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec3(positions.x, positions.y, depth),
|
||||
glm::vec3(positions.z, positions.y, depth),
|
||||
glm::vec3(positions.x, positions.w, depth),
|
||||
glm::vec3(positions.z, positions.w, depth)
|
||||
};
|
||||
|
||||
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec2(coordinates.x, coordinates.y),
|
||||
glm::vec2(coordinates.z, coordinates.y),
|
||||
glm::vec2(coordinates.x, coordinates.w),
|
||||
glm::vec2(coordinates.z, coordinates.w)
|
||||
};
|
||||
|
||||
int32_t indices[QUAD_INDICE_COUNT] = {
|
||||
verticeStart, verticeStart + 1, verticeStart + 3,
|
||||
verticeStart, verticeStart + 2, verticeStart + 3
|
||||
};
|
||||
|
||||
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
|
||||
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
|
||||
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferWithIndex(
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const glm::vec4 positions,
|
||||
const glm::vec4 coordinates,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart,
|
||||
const int32_t indexOffset
|
||||
) {
|
||||
glm::vec3 vertices[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec3(positions.x, positions.y, indexOffset),
|
||||
glm::vec3(positions.z, positions.y, indexOffset + 1),
|
||||
glm::vec3(positions.x, positions.w, indexOffset + 2),
|
||||
glm::vec3(positions.z, positions.w, indexOffset + 3)
|
||||
};
|
||||
|
||||
glm::vec2 coords[QUAD_VERTICE_COUNT] = {
|
||||
glm::vec2(coordinates.x, coordinates.y),
|
||||
glm::vec2(coordinates.z, coordinates.y),
|
||||
glm::vec2(coordinates.x, coordinates.w),
|
||||
glm::vec2(coordinates.z, coordinates.w)
|
||||
};
|
||||
|
||||
int32_t indices[QUAD_INDICE_COUNT] = {
|
||||
verticeStart, verticeStart + 1, verticeStart + 3,
|
||||
verticeStart, verticeStart + 2, verticeStart + 3
|
||||
};
|
||||
|
||||
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
|
||||
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
|
||||
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
|
||||
}
|
55
src/dawn/display/mesh/QuadMesh.hpp
Normal file
55
src/dawn/display/mesh/QuadMesh.hpp
Normal file
@ -0,0 +1,55 @@
|
||||
// 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"
|
||||
|
||||
#define QUAD_VERTICE_COUNT 4
|
||||
#define QUAD_INDICE_COUNT 6
|
||||
|
||||
namespace Dawn {
|
||||
class QuadMesh {
|
||||
public:
|
||||
/**
|
||||
* Buffers quad mesh vertices and indices into the given mesh.
|
||||
*
|
||||
* @param mesh The mesh to buffer into.
|
||||
* @param positions The positions of the vertices.
|
||||
* @param coordinates The coordinates of the vertices.
|
||||
* @param verticeStart The starting index of the vertices.
|
||||
* @param indiceStart The starting index of the indices.
|
||||
* @param depth The depth of the vertices (Z coordinate).
|
||||
*/
|
||||
static void buffer(
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const glm::vec4 positions,
|
||||
const glm::vec4 coordinates,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart,
|
||||
const float_t depth = 0.0f
|
||||
);
|
||||
|
||||
/**
|
||||
* Buffers quad mesh vertices and indices into the given mesh. This will
|
||||
* store the index of the vertice in the Z component, allowing you to find
|
||||
* which vertex ID you are rendering in your shader.
|
||||
*
|
||||
* @param mesh The mesh to buffer into.
|
||||
* @param positions The positions of the vertices.
|
||||
* @param coordinates The coordinates of the vertices.
|
||||
* @param verticeStart The starting index of the vertices.
|
||||
* @param indiceStart The starting index of the indices.
|
||||
* @param indexOffset The offset to add to the index of each vertex.
|
||||
*/
|
||||
static void bufferWithIndex(
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const glm::vec4 positions,
|
||||
const glm::vec4 coordinates,
|
||||
const int32_t verticeStart,
|
||||
const int32_t indiceStart,
|
||||
const int32_t indexOffset = 0
|
||||
);
|
||||
};
|
||||
}
|
40
src/dawn/display/pass/IRenderPass.hpp
Normal file
40
src/dawn/display/pass/IRenderPass.hpp
Normal file
@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class IRenderPass {
|
||||
public:
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
|
||||
/**
|
||||
* Binds the shader for this render pass.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Sets the data for this render pass to the shader.
|
||||
*/
|
||||
virtual void setData() = 0;
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
virtual void upload() = 0;
|
||||
|
||||
/**
|
||||
* Draws the mesh for this render pass.
|
||||
*/
|
||||
virtual void draw() = 0;
|
||||
|
||||
/**
|
||||
* Cleans up the render pass.
|
||||
*/
|
||||
virtual ~IRenderPass() {
|
||||
}
|
||||
};
|
||||
}
|
94
src/dawn/display/pass/RenderPass.hpp
Normal file
94
src/dawn/display/pass/RenderPass.hpp
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "game/Game.hpp"
|
||||
#include "display/pass/IRenderPass.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "component/display/MeshRenderer.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<class S, typename D>
|
||||
class RenderPass : public IRenderPass {
|
||||
private:
|
||||
std::shared_ptr<S> shader;
|
||||
const std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures;
|
||||
std::shared_ptr<Mesh> mesh;
|
||||
const enum MeshDrawMode drawMode;
|
||||
const int32_t indiceStart;
|
||||
const int32_t indiceCount;
|
||||
const D data;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a new RenderPass.
|
||||
*
|
||||
* @param self Self component instance that is creating this render pass.
|
||||
* @param d The data to use for this render pass.
|
||||
* @param mesh The mesh to use for this render pass.
|
||||
* @param drawMode The draw mode to use for this render pass.
|
||||
* @param indiceStart The indice to start drawing from.
|
||||
* @param indiceCount The number of indices to draw.
|
||||
*/
|
||||
RenderPass(
|
||||
SceneComponent &self,
|
||||
const D d,
|
||||
const std::unordered_map<
|
||||
shadertexturebinding_t, std::shared_ptr<Texture>
|
||||
> textures,
|
||||
const std::shared_ptr<Mesh> mesh,
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t indiceStart,
|
||||
const int32_t indiceCount
|
||||
) :
|
||||
data(d),
|
||||
textures(textures),
|
||||
mesh(mesh),
|
||||
drawMode(drawMode),
|
||||
indiceStart(indiceStart),
|
||||
indiceCount(indiceCount)
|
||||
{
|
||||
//Get the shader
|
||||
shader = (
|
||||
self.getGame()->renderHost.shaderManager.getShader<S>()
|
||||
);
|
||||
assertNotNull(shader, "Shader cannot be null!");
|
||||
|
||||
// Need mesh?
|
||||
if(!this->mesh) {
|
||||
auto meshRenderer = self.getItem()->getComponent<MeshRenderer>();
|
||||
if(meshRenderer) this->mesh = meshRenderer->mesh;
|
||||
}
|
||||
}
|
||||
|
||||
void bind() override {
|
||||
shader->bind();
|
||||
}
|
||||
|
||||
void setData() override {
|
||||
shader->setData(data);
|
||||
}
|
||||
|
||||
void upload() override {
|
||||
for(auto &pair : textures) {
|
||||
if(!pair.second->isReady()) continue;
|
||||
pair.second->bind(pair.first);
|
||||
}
|
||||
shader->upload();
|
||||
}
|
||||
|
||||
void draw() override {
|
||||
if(mesh) {
|
||||
mesh->draw(drawMode, indiceStart, indiceCount);
|
||||
}
|
||||
}
|
||||
|
||||
~RenderPass() override {
|
||||
}
|
||||
};
|
||||
}
|
18
src/dawn/display/pass/RenderPassContext.hpp
Normal file
18
src/dawn/display/pass/RenderPassContext.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "game/Game.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "component/display/Camera.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct RenderPassContext {
|
||||
std::shared_ptr<Game> game;
|
||||
std::shared_ptr<Scene> scene;
|
||||
std::shared_ptr<Camera> camera;
|
||||
std::shared_ptr<RenderTarget> renderTarget;
|
||||
};
|
||||
}
|
11
src/dawn/display/shader/CMakeLists.txt
Normal file
11
src/dawn/display/shader/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# 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
|
||||
IShader.cpp
|
||||
IShaderStage.cpp
|
||||
)
|
46
src/dawn/display/shader/IShader.cpp
Normal file
46
src/dawn/display/shader/IShader.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
size_t shaderParameterTypeGetSize(const enum ShaderParameterType type) {
|
||||
switch(type) {
|
||||
case ShaderParameterType::VEC2:
|
||||
return sizeof(glm::vec2);
|
||||
|
||||
case ShaderParameterType::VEC3:
|
||||
return sizeof(glm::vec3);
|
||||
|
||||
case ShaderParameterType::VEC4:
|
||||
return sizeof(glm::vec4);
|
||||
|
||||
case ShaderParameterType::MAT3:
|
||||
return sizeof(glm::mat3);
|
||||
|
||||
case ShaderParameterType::MAT4:
|
||||
return sizeof(glm::mat4);
|
||||
|
||||
case ShaderParameterType::COLOR:
|
||||
return sizeof(struct Color);
|
||||
|
||||
case ShaderParameterType::FLOAT:
|
||||
return sizeof(float);
|
||||
|
||||
case ShaderParameterType::INT:
|
||||
return sizeof(int32_t);
|
||||
|
||||
case ShaderParameterType::TEXTURE:
|
||||
return sizeof(shadertexturebinding_t);
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown ShaderParameterType");
|
||||
return 0;
|
||||
}
|
||||
}
|
86
src/dawn/display/shader/IShader.hpp
Normal file
86
src/dawn/display/shader/IShader.hpp
Normal file
@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderParameterType {
|
||||
VEC2,
|
||||
VEC3,
|
||||
VEC4,
|
||||
MAT3,
|
||||
MAT4,
|
||||
COLOR,
|
||||
FLOAT,
|
||||
INT,
|
||||
TEXTURE,
|
||||
BOOLEAN
|
||||
};
|
||||
|
||||
class IShaderBase {
|
||||
public:
|
||||
virtual ~IShaderBase() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class IShader : public IShaderBase {
|
||||
protected:
|
||||
T data;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Returns the currently uploaded data on the Shader.
|
||||
*
|
||||
* @return The uploaded data.
|
||||
*/
|
||||
T getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the entire data to be uploaded.
|
||||
*
|
||||
* @param data Data to be uploaded.
|
||||
*/
|
||||
void setData(const T data) {
|
||||
this->data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the shader, this needs to be called before the shader can
|
||||
* be used.
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Binds the shader as the current one, does not upload any data, somewhat
|
||||
* relies on something else uploading the data.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
virtual void upload() = 0;
|
||||
|
||||
/**
|
||||
* Disposes of the shader.
|
||||
*/
|
||||
virtual ~IShader() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size of the ShaderParameterType.
|
||||
*
|
||||
* @param type The type to get the size of.
|
||||
* @return Size of the type.
|
||||
*/
|
||||
size_t shaderParameterTypeGetSize(const enum Dawn::ShaderParameterType type);
|
18
src/dawn/display/shader/IShaderStage.cpp
Normal file
18
src/dawn/display/shader/IShaderStage.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "IShaderStage.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
IShaderStage::IShaderStage(const enum ShaderStageType type) :
|
||||
type(type)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
IShaderStage::~IShaderStage() {
|
||||
|
||||
}
|
32
src/dawn/display/shader/IShaderStage.hpp
Normal file
32
src/dawn/display/shader/IShaderStage.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderStageType {
|
||||
VERTEX,
|
||||
FRAGMENT,
|
||||
// COMPUTE
|
||||
};
|
||||
|
||||
class IShaderStage {
|
||||
public:
|
||||
const enum ShaderStageType type;
|
||||
|
||||
/**
|
||||
* Constructs a new Shader Stage.
|
||||
*
|
||||
* @param type Type of shader stage.
|
||||
*/
|
||||
IShaderStage(const enum ShaderStageType type);
|
||||
|
||||
/**
|
||||
* Destroy the IShaderStage object
|
||||
*/
|
||||
virtual ~IShaderStage();
|
||||
};
|
||||
}
|
45
src/dawn/display/shader/ShaderManager.hpp
Normal file
45
src/dawn/display/shader/ShaderManager.hpp
Normal file
@ -0,0 +1,45 @@
|
||||
// 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 {
|
||||
class ShaderManager {
|
||||
private:
|
||||
std::vector<std::shared_ptr<IShaderBase>> shaders;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Retreives an instance of the shader from the shader manager. If the
|
||||
* shader does not exist it will be created.
|
||||
*
|
||||
* @tparam T Type of shader to retreive.
|
||||
* @return Shader instance.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getShader() {
|
||||
auto itShaders = shaders.begin();
|
||||
while(itShaders != shaders.end()) {
|
||||
// auto shader = itShaders->lock();
|
||||
// if(!shader) {
|
||||
// itShaders = shaders.erase(itShaders);
|
||||
// continue;
|
||||
// }
|
||||
// std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
|
||||
|
||||
auto shader = *itShaders;
|
||||
std::shared_ptr<T> casted = std::dynamic_pointer_cast<T>(shader);
|
||||
if(casted) return casted;
|
||||
itShaders++;
|
||||
}
|
||||
|
||||
auto newShader = std::make_shared<T>();
|
||||
shaders.push_back(newShader);
|
||||
newShader->init();
|
||||
return newShader;
|
||||
}
|
||||
};
|
||||
}
|
9
src/dawn/error/CMakeLists.txt
Normal file
9
src/dawn/error/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2022 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
assert.cpp
|
||||
)
|
@ -5,12 +5,21 @@
|
||||
|
||||
#include "assert.hpp"
|
||||
|
||||
void assertTrue(bool condition, const char_t *message, ...) {
|
||||
if (!condition) {
|
||||
void assertTrueImplement(
|
||||
const char *file,
|
||||
const int32_t line,
|
||||
const char *func,
|
||||
const bool_t result,
|
||||
const char *message,
|
||||
...
|
||||
) {
|
||||
if(!result) {
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
fprintf(stderr, "Assertion failed in %s:%d (%s): ", file, line, func);
|
||||
vfprintf(stderr, message, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
exit(EXIT_FAILURE);
|
||||
exit(1);
|
||||
}
|
||||
}
|
@ -1,17 +1,115 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
/**
|
||||
* Asserts a statement to be true, if not true a failed assertion is thrown
|
||||
* and a program halt is requested.
|
||||
* Asserts that a given statement must evaluate to true or the assertion fails
|
||||
* and the game will close semi-gracefully.
|
||||
*
|
||||
* @param condition The condition to assert.
|
||||
* @param message Message to display if assertion is false.
|
||||
* @param ...args Arguments to format the message with. (Sprintf)
|
||||
* @param file String filename of the file that has the assertion.
|
||||
* @param line Integer line number within the file that the assertion is on.
|
||||
* @param func Called function that has the assertion.
|
||||
* @param result The statement that must equate to true.
|
||||
* @param message Message (sprintf format) to send to the stdout.
|
||||
* @param ... Varargs of the sprintf arguments.
|
||||
*/
|
||||
static void assertTrue(bool condition, const char_t *message, ...);
|
||||
void assertTrueImplement(
|
||||
const char *file,
|
||||
const int32_t line,
|
||||
const char *func,
|
||||
const bool_t result,
|
||||
const char *message,
|
||||
...
|
||||
);
|
||||
|
||||
/**
|
||||
* Asserts that a statement must be true in order for the assertion to not cause
|
||||
* an error. Basically this is a throw statement in disguise.
|
||||
*
|
||||
* @param statement Statement of the assertion.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertTrue(...) assertTrueImplement( \
|
||||
__FILE__, __LINE__, __func__, __VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Asserts that a statement must be false in order for the assertion to not
|
||||
* cause an error.
|
||||
*
|
||||
* @param statement Statement of the assertion.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertFalse(x, ...) assertTrue(!(x), __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Asserts that a specified piece of code should be entirely unreachable.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertUnreachable(...) assertTrue(false, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Asserts that a given pointer is not null.
|
||||
* @param x Pointer to check.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertNotNull(x, ...) assertTrue(x != nullptr, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Asserts that a given pointer is null.
|
||||
* @param x Pointer to check.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertNull(x, ...) assertTrue(x == nullptr, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Asserts that a given map has a specific key.
|
||||
* @param map Map to check.
|
||||
* @param key Key to check for.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertMapHasKey(map, key, ...) assertTrue( \
|
||||
map.find(key) != map.end(), __VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Asserts that a given value has a specific flag turned off.
|
||||
*
|
||||
* @param value Value to check.
|
||||
* @param flag Flag to check for.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertFlagOff(value, flag, ...) assertTrue( \
|
||||
(value & flag) == 0, __VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Asserts that a given value has a specific flag turned on.
|
||||
*
|
||||
* @param value Value to check.
|
||||
* @param flag Flag to check for.
|
||||
* @param message Message (sprintf format) to send to the logger.
|
||||
* @param args Optional TParam args for the sprintf message to accept.
|
||||
*/
|
||||
#define assertFlagOn(value, flag, ...) assertTrue( \
|
||||
(value & flag) == flag, __VA_ARGS__ \
|
||||
)
|
||||
|
||||
/**
|
||||
* Asserts that the current code is deprecated and should not be used anymore.
|
||||
* @deprecated
|
||||
*/
|
||||
#define assertDeprecated(...) assertUnreachable(__VA_ARGS__)
|
22
src/dawn/error/error.hpp
Normal file
22
src/dawn/error/error.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
/**
|
||||
* Shows an error message box on the host device. This method should be blocking
|
||||
* and should not return until the user has acknowledged the error.
|
||||
*
|
||||
* @param message Message to display.
|
||||
*/
|
||||
void errorMessageBox(const std::u8string &message);
|
||||
|
||||
/**
|
||||
* Logs an error message to the host device.
|
||||
*
|
||||
* @param message Message to log.
|
||||
*/
|
||||
void errorLog(const std::string &message);
|
141
src/dawn/event/CustomEvent.hpp
Normal file
141
src/dawn/event/CustomEvent.hpp
Normal file
@ -0,0 +1,141 @@
|
||||
// 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 {
|
||||
enum class CustomEventResult {
|
||||
NOTHING,
|
||||
REMOVE,
|
||||
INVOKE,
|
||||
INVOKE_AND_REMOVE
|
||||
};
|
||||
|
||||
template<
|
||||
typename InternalData,
|
||||
typename InternalListenerData,
|
||||
typename ListenerArgument,
|
||||
typename ...InvokeArgs
|
||||
>
|
||||
class CustomEvent {
|
||||
private:
|
||||
int32_t nextId = 0;
|
||||
std::unordered_map<
|
||||
int32_t,
|
||||
std::pair<InternalListenerData, std::function<void(InvokeArgs...)>>
|
||||
> listeners;
|
||||
|
||||
protected:
|
||||
InternalData internalData;
|
||||
|
||||
/**
|
||||
* Custom event filter. Decides whether or not the event should be emitted
|
||||
* to the listener.
|
||||
*
|
||||
* @param listenerData Data for this listener.
|
||||
* @param args The arguments to pass to the listeners.
|
||||
* @return The result of the filter.
|
||||
*/
|
||||
virtual enum CustomEventResult shouldEmit(
|
||||
const InternalListenerData &listenerData,
|
||||
const InvokeArgs... args
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Transform the arguments for listener data when the listener is first
|
||||
* subscribed.
|
||||
*
|
||||
* @param argument The argument to transform.
|
||||
* @return The transformed argument into an internal data format.
|
||||
*/
|
||||
virtual InternalListenerData transformData(
|
||||
const ListenerArgument &argument
|
||||
) = 0;
|
||||
|
||||
/**
|
||||
* Transform the data for listener data after the event has been emitted.
|
||||
*
|
||||
* @param internalData The internal data to transform.
|
||||
* @return Updated/Transformed internal data.
|
||||
*/
|
||||
virtual InternalListenerData transformDataAfterEmit(
|
||||
const InternalListenerData &internalData
|
||||
) {
|
||||
return internalData;
|
||||
}
|
||||
|
||||
public:
|
||||
/**
|
||||
* Emits the event.
|
||||
* @param args The arguments to pass to the listeners.
|
||||
*/
|
||||
void emit(InvokeArgs... args) {
|
||||
auto copy = listeners;
|
||||
for(auto &pair : copy) {
|
||||
// Check emit test.
|
||||
auto result = this->shouldEmit(
|
||||
pair.second.first,
|
||||
args...
|
||||
);
|
||||
if(
|
||||
result == CustomEventResult::INVOKE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
pair.second.second(args...);
|
||||
}
|
||||
|
||||
if(
|
||||
result == CustomEventResult::REMOVE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
listeners.erase(pair.first);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(
|
||||
result == CustomEventResult::INVOKE ||
|
||||
result == CustomEventResult::INVOKE_AND_REMOVE
|
||||
) {
|
||||
// Update the internal data.
|
||||
listeners[pair.first].first = transformDataAfterEmit(
|
||||
pair.second.first
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the event.
|
||||
*
|
||||
* @param data Listener data to use.
|
||||
* @param listener The listener to add.
|
||||
* @returns A function that can be called to remove the listener.
|
||||
*/
|
||||
std::function<void()> listen(
|
||||
const ListenerArgument &data,
|
||||
const std::function<void(InvokeArgs...)> listener
|
||||
) {
|
||||
int32_t id = nextId++;
|
||||
|
||||
auto pair = std::make_pair(
|
||||
transformData(data),
|
||||
listener
|
||||
);
|
||||
|
||||
listeners[id] = pair;
|
||||
return [this, id]() {
|
||||
listeners.erase(id);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the custom event.
|
||||
*/
|
||||
virtual ~CustomEvent() {
|
||||
listeners.clear();
|
||||
}
|
||||
};
|
||||
}
|
57
src/dawn/event/Event.hpp
Normal file
57
src/dawn/event/Event.hpp
Normal file
@ -0,0 +1,57 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
template<typename ...A>
|
||||
class Event {
|
||||
private:
|
||||
int32_t nextId = 0;
|
||||
std::map<int32_t, std::function<void(A...)>> listeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Constructs a new Event.
|
||||
*/
|
||||
Event() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Emits the event.
|
||||
* @param args The arguments to pass to the listeners.
|
||||
*/
|
||||
void emit(A ...args) {
|
||||
auto copy = listeners;
|
||||
for(auto &pair : copy) {
|
||||
pair.second(args...);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Listens to the event.
|
||||
* @param listener The listener to add.
|
||||
* @returns A function that can be called to remove the listener.
|
||||
*/
|
||||
std::function<void()> listen(
|
||||
const std::function<void(A...)> listener
|
||||
) {
|
||||
int32_t id = nextId++;
|
||||
listeners[id] = listener;
|
||||
return [this, id]() {
|
||||
listeners.erase(id);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the event.
|
||||
*/
|
||||
virtual ~Event() {
|
||||
listeners.clear();
|
||||
}
|
||||
};
|
||||
}
|
9
src/dawn/game/CMakeLists.txt
Normal file
9
src/dawn/game/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Game.cpp
|
||||
)
|
34
src/dawn/game/Game.cpp
Normal file
34
src/dawn/game/Game.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Game.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Game::Game() :
|
||||
renderManager()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
std::shared_ptr<Scene> Game::getCurrentScene() {
|
||||
return currentScene;
|
||||
}
|
||||
|
||||
void Game::setCurrentScene(std::shared_ptr<Scene> scene) {
|
||||
currentScene = scene;
|
||||
}
|
||||
|
||||
void Game::init() {
|
||||
renderManager.init(*this);
|
||||
}
|
||||
|
||||
void Game::update() {
|
||||
renderManager.update(*this);
|
||||
}
|
||||
|
||||
Game::~Game() {
|
||||
|
||||
}
|
@ -5,10 +5,18 @@
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "display/RenderManager.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Game {
|
||||
class Scene;
|
||||
|
||||
class Game : std::enable_shared_from_this<Game> {
|
||||
private:
|
||||
std::shared_ptr<Scene> currentScene;
|
||||
|
||||
public:
|
||||
RenderManager renderManager;
|
||||
|
||||
/**
|
||||
* Constructs a new instance of Game, the class majorily responsible for
|
||||
* handling all internal dawn functions outside of platform-centric things
|
||||
@ -16,6 +24,30 @@ namespace Dawn {
|
||||
*/
|
||||
Game();
|
||||
|
||||
/**
|
||||
* Gets the current scene.
|
||||
*
|
||||
* @return The current scene.
|
||||
*/
|
||||
std::shared_ptr<Scene> getCurrentScene();
|
||||
|
||||
/**
|
||||
* Sets the current scene to the provided scene.
|
||||
*
|
||||
* @param scene The scene to set as the current scene.
|
||||
*/
|
||||
void setCurrentScene(std::shared_ptr<Scene> scene);
|
||||
|
||||
/**
|
||||
* Initializes the game and all sub managers used by game.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Updates the game and all sub managers used by game.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Deloads game and all sub managers used by game.
|
||||
*/
|
||||
|
10
src/dawn/locale/CMakeLists.txt
Normal file
10
src/dawn/locale/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Language.cpp
|
||||
)
|
15
src/dawn/locale/Language.cpp
Normal file
15
src/dawn/locale/Language.cpp
Normal file
@ -0,0 +1,15 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Language.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::u8string Language::get(
|
||||
const char_t key[],
|
||||
const std::pair<std::string, std::u8string> &args
|
||||
) {
|
||||
return u8"Some language string 👍";
|
||||
}
|
24
src/dawn/locale/Language.hpp
Normal file
24
src/dawn/locale/Language.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Language {
|
||||
public:
|
||||
/**
|
||||
* Gets a language string from the language definition set.
|
||||
*
|
||||
* @param key The key to look up in the language file.
|
||||
* @param args A pair of strings to replace in the language string.
|
||||
* @return The language string.
|
||||
*/
|
||||
static std::u8string get(
|
||||
const char_t key[],
|
||||
const std::pair<std::string, std::u8string> &args = std::make_pair("", u8"")
|
||||
);
|
||||
};
|
||||
}
|
10
src/dawn/scene/CMakeLists.txt
Normal file
10
src/dawn/scene/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Scene.cpp
|
||||
)
|
16
src/dawn/scene/Scene.cpp
Normal file
16
src/dawn/scene/Scene.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Scene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Scene::Scene() {
|
||||
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
|
||||
}
|
22
src/dawn/scene/Scene.hpp
Normal file
22
src/dawn/scene/Scene.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Scene {
|
||||
public:
|
||||
/**
|
||||
* Scene Constructor.
|
||||
*/
|
||||
Scene();
|
||||
|
||||
/**
|
||||
* Scene Destructor.
|
||||
*/
|
||||
~Scene();
|
||||
};
|
||||
}
|
9
src/dawn/util/CMakeLists.txt
Normal file
9
src/dawn/util/CMakeLists.txt
Normal file
@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
string.cpp
|
||||
)
|
35
src/dawn/util/string.cpp
Normal file
35
src/dawn/util/string.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "string.hpp"
|
||||
|
||||
bool_t stringIncludes(
|
||||
const std::string &haystack,
|
||||
const std::string &needle
|
||||
) {
|
||||
return haystack.find(needle) != std::string::npos;
|
||||
}
|
||||
|
||||
std::string stringToLowercase(const std::string &str) {
|
||||
std::string lower = str;
|
||||
std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
|
||||
return lower;
|
||||
}
|
||||
|
||||
std::vector<std::string> stringSplit(
|
||||
const std::string &str,
|
||||
const std::string &delim
|
||||
) {
|
||||
std::vector<std::string> parts;
|
||||
size_t start = 0;
|
||||
size_t end = str.find(delim);
|
||||
while(end != std::string::npos) {
|
||||
parts.push_back(str.substr(start, end - start));
|
||||
start = end + delim.length();
|
||||
end = str.find(delim, start);
|
||||
}
|
||||
parts.push_back(str.substr(start, end));
|
||||
return parts;
|
||||
}
|
36
src/dawn/util/string.hpp
Normal file
36
src/dawn/util/string.hpp
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
/**
|
||||
* Returns true if the haystack string includes the needle string.
|
||||
* @param haystack The string to search in.
|
||||
* @param needle The string to search for.
|
||||
* @return True if the needle is found in the haystack.
|
||||
*/
|
||||
bool_t stringIncludes(
|
||||
const std::string &haystack,
|
||||
const std::string &needle
|
||||
);
|
||||
|
||||
/**
|
||||
* Converts a string to lowercase.
|
||||
* @param str The string to convert.
|
||||
* @return The lowercase version of the string.
|
||||
*/
|
||||
std::string stringToLowercase(const std::string &str);
|
||||
|
||||
/**
|
||||
* Splits a string by a delimiter.
|
||||
* @param str The string to split.
|
||||
* @param delim The delimiter to split by.
|
||||
* @return A vector of strings split by the delimiter.
|
||||
*/
|
||||
std::vector<std::string> stringSplit(
|
||||
const std::string &str,
|
||||
const std::string &delim
|
||||
);
|
@ -9,6 +9,7 @@ target_link_libraries(${DAWN_TARGET_NAME}
|
||||
glfw
|
||||
glad
|
||||
archive_static
|
||||
Boxer
|
||||
)
|
||||
|
||||
# Includes
|
||||
@ -24,4 +25,6 @@ target_sources(${DAWN_TARGET_NAME}
|
||||
# input.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
# Subdirs
|
||||
add_subdirectory(error)
|
||||
add_subdirectory(host)
|
7
src/dawnglfw/dawnopengl.hpp
Normal file
7
src/dawnglfw/dawnopengl.hpp
Normal file
@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <glad/glad.h>
|
10
src/dawnglfw/error/CMakeLists.txt
Normal file
10
src/dawnglfw/error/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
error.cpp
|
||||
)
|
27
src/dawnglfw/error/error.cpp
Normal file
27
src/dawnglfw/error/error.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "error/error.hpp"
|
||||
#include <boxer/boxer.h>
|
||||
|
||||
void errorMessageBox(const std::u8string &message) {
|
||||
std::string titleStr = DAWN_GAME_NAME;
|
||||
std::string messageStr = (
|
||||
message.length() > 0 ?
|
||||
std::string(message.cbegin(), message.cend()) :
|
||||
std::string()
|
||||
);
|
||||
|
||||
boxer::show(
|
||||
messageStr.c_str(),
|
||||
titleStr.c_str(),
|
||||
boxer::Style::Error,
|
||||
boxer::Buttons::Quit
|
||||
);
|
||||
}
|
||||
|
||||
void errorLog(const std::string &message) {
|
||||
std::cerr << message << std::endl;
|
||||
}
|
10
src/dawnglfw/host/CMakeLists.txt
Normal file
10
src/dawnglfw/host/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# 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
|
||||
DawnGLFWHost.cpp
|
||||
)
|
150
src/dawnglfw/host/DawnGLFWHost.cpp
Normal file
150
src/dawnglfw/host/DawnGLFWHost.cpp
Normal file
@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "DawnGLFWHost.hpp"
|
||||
#include "error/error.hpp"
|
||||
#include "locale/Language.hpp"
|
||||
#include "error/erroropengl.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
DawnGLFWHost::DawnGLFWHost() {
|
||||
|
||||
}
|
||||
|
||||
DawnGLFWInitResult DawnGLFWHost::init(
|
||||
const int32_t argc, const char_t **argv
|
||||
) {
|
||||
if(!glfwInit()) {
|
||||
errorLog("GLFW failed to initialize.");
|
||||
errorMessageBox(Language::get("glfw.error.glfw_init"));
|
||||
return DawnGLFWInitResult::GLFW_INIT_FAILED;
|
||||
}
|
||||
|
||||
// Setup window hints
|
||||
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
|
||||
// Create window
|
||||
this->window = glfwCreateWindow(
|
||||
DAWN_GLFW_WIDTH_DEFAULT,
|
||||
DAWN_GLFW_HEIGHT_DEFAULT,
|
||||
DAWN_GAME_NAME,
|
||||
NULL,
|
||||
NULL
|
||||
);
|
||||
|
||||
if(this->window == nullptr) {
|
||||
errorLog("GLFW failed to create window.");
|
||||
errorMessageBox(Language::get("glfw.error.window_create"));
|
||||
glfwTerminate();
|
||||
return DawnGLFWInitResult::WINDOW_CREATE_FAILED;
|
||||
}
|
||||
|
||||
// Set back pointer
|
||||
glfwSetWindowUserPointer(this->window, this);
|
||||
|
||||
// Load GLAD
|
||||
glfwMakeContextCurrent(this->window);
|
||||
glfwSwapInterval(1);
|
||||
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
|
||||
try {
|
||||
errorCheckOpenGL();
|
||||
} catch(const std::runtime_error &e) {
|
||||
errorLog(e.what());
|
||||
errorMessageBox(Language::get("glfw.error.opengl_error"));
|
||||
glfwTerminate();
|
||||
return DawnGLFWInitResult::GLAD_GL_CHECK_FAILED;
|
||||
}
|
||||
|
||||
// Override the defaults
|
||||
int32_t fbWidth, fbHeight;
|
||||
glfwGetFramebufferSize(this->window, &fbWidth, &fbHeight);
|
||||
glfwGetWindowSize(this->window, &this->windowWidth, &this->windowHeight);
|
||||
try {
|
||||
errorCheckOpenGL();
|
||||
} catch(const std::runtime_error &e) {
|
||||
errorLog(e.what());
|
||||
errorMessageBox(Language::get("glfw.error.opengl_error"));
|
||||
glfwTerminate();
|
||||
return DawnGLFWInitResult::GLAD_GL_CHECK_FAILED;
|
||||
}
|
||||
|
||||
if(
|
||||
fbWidth == 0 ||
|
||||
fbHeight == 0 ||
|
||||
this->windowWidth == 0 ||
|
||||
this->windowHeight == 0
|
||||
) {
|
||||
errorLog(
|
||||
"GLFW Returned incorrect size: " +
|
||||
std::to_string(fbWidth) + "x" + std::to_string(fbHeight) + " / " +
|
||||
std::to_string(windowWidth) + "x" + std::to_string(windowHeight)
|
||||
);
|
||||
errorMessageBox(Language::get("glfw.error.viewport_size"));
|
||||
glfwTerminate();
|
||||
return DawnGLFWInitResult::VIEWPORT_SIZE_FAILED;
|
||||
}
|
||||
|
||||
// Init Game
|
||||
this->game = std::make_shared<Game>();
|
||||
this->game->init();
|
||||
|
||||
auto backBuffer = this->game->renderManager.getBackBufferRenderTarget();
|
||||
backBuffer->setSize((float_t)fbWidth, (float_t)fbHeight);
|
||||
|
||||
// Set up callbacks
|
||||
glfwSetFramebufferSizeCallback(this->window, [](
|
||||
GLFWwindow *window,
|
||||
int32_t width,
|
||||
int32_t height
|
||||
) {
|
||||
auto host = (DawnGLFWHost*)glfwGetWindowUserPointer(window);
|
||||
if(host == nullptr) return;
|
||||
host->windowWidth = width;
|
||||
host->windowHeight = height;
|
||||
auto backBuffer = host->game->renderManager.getBackBufferRenderTarget();
|
||||
backBuffer->setSize((float_t)width, (float_t)height);
|
||||
});
|
||||
|
||||
return DawnGLFWInitResult::SUCCESS;
|
||||
}
|
||||
|
||||
void DawnGLFWHost::start() {
|
||||
double_t time, newTime;
|
||||
float_t fDelta;
|
||||
int32_t updateResult;
|
||||
|
||||
// Main Render Loop
|
||||
time = 0.0f;
|
||||
while(!glfwWindowShouldClose(this->window)) {
|
||||
// Determine the delta.
|
||||
newTime = glfwGetTime();
|
||||
fDelta = (float_t)(newTime - time);
|
||||
time = newTime;
|
||||
|
||||
// Update the game
|
||||
this->game->update();
|
||||
|
||||
// Update GLFW
|
||||
glfwSwapBuffers(this->window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
|
||||
this->game = nullptr;
|
||||
}
|
||||
|
||||
DawnGLFWHost::~DawnGLFWHost() {
|
||||
this->game = nullptr;
|
||||
|
||||
// Terminate GLFW
|
||||
if(this->window != nullptr) {
|
||||
glfwDestroyWindow(this->window);
|
||||
glfwTerminate();
|
||||
}
|
||||
}
|
54
src/dawnglfw/host/DawnGLFWHost.hpp
Normal file
54
src/dawnglfw/host/DawnGLFWHost.hpp
Normal file
@ -0,0 +1,54 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "dawn.hpp"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "game/Game.hpp"
|
||||
|
||||
#define DAWN_GLFW_WIDTH_DEFAULT 800
|
||||
#define DAWN_GLFW_HEIGHT_DEFAULT 600
|
||||
|
||||
namespace Dawn {
|
||||
enum class DawnGLFWInitResult {
|
||||
SUCCESS = 0,
|
||||
GLFW_INIT_FAILED = 1,
|
||||
WINDOW_CREATE_FAILED = 2,
|
||||
GLAD_GL_CHECK_FAILED = 3,
|
||||
VIEWPORT_SIZE_FAILED = 4
|
||||
};
|
||||
|
||||
class DawnGLFWHost {
|
||||
private:
|
||||
GLFWwindow *window;
|
||||
int32_t windowWidth, windowHeight;
|
||||
std::shared_ptr<Game> game;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new GLFW Host.
|
||||
*/
|
||||
DawnGLFWHost();
|
||||
|
||||
/**
|
||||
* Initializes the GLFW Host.
|
||||
*
|
||||
* @param argc The number of arguments.
|
||||
* @param argv The arguments.
|
||||
*/
|
||||
DawnGLFWInitResult init(const int32_t argc, const char_t **argv);
|
||||
|
||||
/**
|
||||
* Starts the GLFW Host, called after the GLFW Host has been initialized.
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* Destroys the GLFW Host.
|
||||
*/
|
||||
~DawnGLFWHost();
|
||||
};
|
||||
}
|
@ -6,8 +6,14 @@
|
||||
*/
|
||||
|
||||
#include "main.hpp"
|
||||
#include "host/DawnGLFWHost.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
int32_t main(const int32_t argc, const char_t **argv) {
|
||||
std::shared_ptr<DawnGLFWHost> host = std::make_shared<DawnGLFWHost>();
|
||||
host->init(argc, argv);
|
||||
host->start();
|
||||
|
||||
int32_t main(int32_t argc, char_t **argv) {
|
||||
std::cout << "Hello C++" << std::endl;
|
||||
return 0;
|
||||
}
|
@ -15,4 +15,4 @@
|
||||
* @param argv The arguments passed to the program.
|
||||
* @return The exit code of the program.
|
||||
*/
|
||||
int32_t main(int32_t argc, char_t **argv);
|
||||
int32_t main(const int32_t argc, const char_t **argv);
|
@ -10,5 +10,5 @@ target_include_directories(${DAWN_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
# add_subdirectory(assert)
|
||||
# add_subdirectory(display)
|
||||
add_subdirectory(error)
|
||||
add_subdirectory(display)
|
68
src/dawnopengl/display/BackBuffer.cpp
Normal file
68
src/dawnopengl/display/BackBuffer.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "dawnopengl.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "error/assertgl.hpp"
|
||||
#include "BackBuffer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
BackBuffer::BackBuffer() {
|
||||
|
||||
}
|
||||
|
||||
float_t BackBuffer::getScale() {
|
||||
return this->scale;
|
||||
}
|
||||
|
||||
float_t BackBuffer::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
float_t BackBuffer::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
void BackBuffer::setSize(
|
||||
const float_t width,
|
||||
const float_t height
|
||||
) {
|
||||
if(this->width == width && this->height == height) return;
|
||||
|
||||
// Fixes a new bug that it seems GLFW has introduced.
|
||||
this->width = width == 0 ? 1 : width;
|
||||
this->height = height == 0 ? 1 : height;
|
||||
|
||||
onResize.emit(this->width, this->height);
|
||||
}
|
||||
|
||||
void BackBuffer::setClearColor(const struct Color color) {
|
||||
this->clearColor = color;
|
||||
}
|
||||
|
||||
void BackBuffer::clear(const int32_t clearFlags) {
|
||||
glClearColor(clearColor.r, clearColor.g, clearColor.b, 1.0f);
|
||||
assertNoGLError();
|
||||
|
||||
GLbitfield mask = 0;
|
||||
if((clearFlags & RENDER_TARGET_CLEAR_COLOR) == RENDER_TARGET_CLEAR_COLOR) {
|
||||
mask |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
|
||||
if((clearFlags & RENDER_TARGET_CLEAR_DEPTH) == RENDER_TARGET_CLEAR_DEPTH) {
|
||||
mask |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(mask);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void BackBuffer::bind() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
assertNoGLError();
|
||||
glViewport(0, 0, (GLsizei)this->width, (GLsizei)this->height);
|
||||
assertNoGLError();
|
||||
}
|
44
src/dawnopengl/display/BackBuffer.hpp
Normal file
44
src/dawnopengl/display/BackBuffer.hpp
Normal file
@ -0,0 +1,44 @@
|
||||
// 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 "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class BackBuffer final : public RenderTarget {
|
||||
private:
|
||||
float_t width = 1;
|
||||
float_t height = 1;
|
||||
struct Color clearColor = COLOR_CORNFLOWER_BLUE;
|
||||
|
||||
public:
|
||||
float_t scale = 1.0f;
|
||||
|
||||
/**
|
||||
* Construct the back buffer render target.
|
||||
*/
|
||||
BackBuffer();
|
||||
|
||||
float_t getScale() override;
|
||||
float_t getWidth() override;
|
||||
float_t getHeight() override;
|
||||
void setClearColor(const struct Color color) override;
|
||||
void clear(const int32_t) override;
|
||||
void bind() override;
|
||||
|
||||
/**
|
||||
* Requests to modify the viewport directly. This is mostly to be called
|
||||
* by whatever is setting the window/display resolution, so that the
|
||||
* backbuffer can keep track of what the viewport size is. This should
|
||||
* also be DPI aware, e.g. "4k @ 2xDPI, resulting in a 1080p equiv" should
|
||||
* still call this method with 3840, 2160.
|
||||
*
|
||||
* @param width New width of the back buffer.
|
||||
* @param height New height of the back buffer.
|
||||
*/
|
||||
void setSize(const float_t width, const float_t height);
|
||||
};
|
||||
}
|
15
src/dawnopengl/display/CMakeLists.txt
Normal file
15
src/dawnopengl/display/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# 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
|
||||
BackBuffer.cpp
|
||||
Texture.cpp
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(mesh)
|
||||
add_subdirectory(shader)
|
213
src/dawnopengl/display/Texture.cpp
Normal file
213
src/dawnopengl/display/Texture.cpp
Normal file
@ -0,0 +1,213 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "error/assert.hpp"
|
||||
#include "error/assertgl.hpp"
|
||||
#include "Texture.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Texture::bind(const uint8_t slot) {
|
||||
assertTrue(this->id != -1, "Texture is not ready!");
|
||||
glActiveTexture(GL_TEXTURE0 + slot);
|
||||
assertNoGLError();
|
||||
glBindTexture(GL_TEXTURE_2D, this->id);
|
||||
assertNoGLError();
|
||||
this->updateTextureProperties();
|
||||
}
|
||||
|
||||
int32_t Texture::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
int32_t Texture::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
bool_t Texture::isReady() {
|
||||
return this->id != -1;
|
||||
}
|
||||
|
||||
void Texture::setSize(
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const enum TextureFormat format,
|
||||
const enum TextureDataFormat dataFormat
|
||||
) {
|
||||
if(this->id != -1) {
|
||||
glDeleteTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
this->id = -1;
|
||||
}
|
||||
|
||||
int32_t maxSize;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
|
||||
assertTrue(width > 0 && width <= maxSize, "Width is out of bounds!");
|
||||
assertTrue(height > 0 && height <= maxSize, "Height is out of bounds!");
|
||||
|
||||
this->width = width;
|
||||
this->height = height;
|
||||
this->format = format;
|
||||
this->dataFormat = dataFormat;
|
||||
|
||||
glGenTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
if(this->id <= 0) assertUnreachable("Texture generation failed!");
|
||||
|
||||
// Initialize the texture to blank
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
assertNoGLError();
|
||||
this->bufferRaw(NULL);
|
||||
}
|
||||
|
||||
// bool_t Texture::isReady() {
|
||||
// return this->id != -1;
|
||||
// }
|
||||
|
||||
void Texture::updateTextureProperties() {
|
||||
auto setWrapMode = [](GLenum axis, enum TextureWrapMode wm) {
|
||||
switch(wm) {
|
||||
case TextureWrapMode::REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_REPEAT);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::MIRRORED_REPEAT:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_MIRRORED_REPEAT);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::CLAMP_TO_EDGE:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_EDGE);
|
||||
break;
|
||||
|
||||
case TextureWrapMode::CLAMP_TO_BORDER:
|
||||
glTexParameteri(GL_TEXTURE_2D, axis, GL_CLAMP_TO_BORDER);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown wrap mode!");
|
||||
}
|
||||
assertNoGLError();
|
||||
};
|
||||
|
||||
setWrapMode(GL_TEXTURE_WRAP_S, this->wrapModeX);
|
||||
setWrapMode(GL_TEXTURE_WRAP_T, this->wrapModeY);
|
||||
|
||||
auto setFilterMode = [](
|
||||
GLenum minMag,
|
||||
enum TextureFilterMode filter,
|
||||
enum TextureFilterMode mapFilterMode
|
||||
) {
|
||||
switch(filter) {
|
||||
case TextureFilterMode::NEAREST: {
|
||||
glTexParameteri(GL_TEXTURE_2D, minMag, GL_NEAREST);
|
||||
break;
|
||||
}
|
||||
|
||||
case TextureFilterMode::LINEAR: {
|
||||
glTexParameteri(GL_TEXTURE_2D, minMag, GL_LINEAR);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unknown filter mode!");
|
||||
}
|
||||
}
|
||||
assertNoGLError();
|
||||
};
|
||||
|
||||
setFilterMode(
|
||||
GL_TEXTURE_MIN_FILTER, this->filterModeMin, this->mipMapFilterModeMin
|
||||
);
|
||||
setFilterMode(
|
||||
GL_TEXTURE_MAG_FILTER, this->filterModeMag, this->mipMapFilterModeMag
|
||||
);
|
||||
}
|
||||
|
||||
void Texture::bufferRaw(const void *data) {
|
||||
assertTrue(this->id != -1, "Texture is not ready!");
|
||||
|
||||
GLenum format;
|
||||
switch(this->format) {
|
||||
case TextureFormat::R:
|
||||
format = GL_RED;
|
||||
break;
|
||||
|
||||
case TextureFormat::RG:
|
||||
format = GL_RG;
|
||||
break;
|
||||
|
||||
case TextureFormat::RGB:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
|
||||
case TextureFormat::RGBA:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture format!");
|
||||
}
|
||||
|
||||
GLenum dataFormat;
|
||||
switch(this->dataFormat) {
|
||||
case TextureDataFormat::UNSIGNED_BYTE:
|
||||
dataFormat = GL_UNSIGNED_BYTE;
|
||||
break;
|
||||
|
||||
case TextureDataFormat::FLOAT:
|
||||
dataFormat = GL_FLOAT;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture data format!");
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, this->id);
|
||||
assertNoGLError();
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, format,
|
||||
this->width, this->height,
|
||||
0, format, dataFormat, data
|
||||
);
|
||||
assertNoGLError();
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Texture::buffer(const struct ColorU8 pixels[]) {
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
|
||||
"Texture data format must be unsigned byte!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
void Texture::buffer(const struct Color pixels[]) {
|
||||
std::cout << "Correct buffer" << std::endl;
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::FLOAT,
|
||||
"Texture data format must be float!"
|
||||
);
|
||||
assertTrue(
|
||||
this->format == TextureFormat::RGBA,
|
||||
"Texture format must be RGBA!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
void Texture::buffer(const uint8_t pixels[]) {
|
||||
assertTrue(
|
||||
this->dataFormat == TextureDataFormat::UNSIGNED_BYTE,
|
||||
"Texture data format must be unsigned byte!"
|
||||
);
|
||||
this->bufferRaw((void*)pixels);
|
||||
}
|
||||
|
||||
Texture::~Texture() {
|
||||
if(this->id != -1) {
|
||||
glDeleteTextures(1, &this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
43
src/dawnopengl/display/Texture.hpp
Normal file
43
src/dawnopengl/display/Texture.hpp
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/ITexture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TextureRenderTarget;
|
||||
|
||||
typedef GLuint textureslot_t;
|
||||
|
||||
class Texture : public ITexture {
|
||||
private:
|
||||
int32_t width = -1;
|
||||
int32_t height = -1;
|
||||
GLuint id = -1;
|
||||
enum TextureFormat format;
|
||||
enum TextureDataFormat dataFormat;
|
||||
|
||||
void updateTextureProperties();
|
||||
void bufferRaw(const void *data);
|
||||
|
||||
public:
|
||||
int32_t getWidth() override;
|
||||
int32_t getHeight() override;
|
||||
void setSize(
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const enum TextureFormat format,
|
||||
const enum TextureDataFormat dataForat
|
||||
) override;
|
||||
bool_t isReady() override;
|
||||
void buffer(const struct ColorU8 pixels[]) override;
|
||||
void buffer(const struct Color pixels[]);
|
||||
void buffer(const uint8_t pixels[]) override;
|
||||
void bind(const uint8_t slot) override;
|
||||
|
||||
~Texture();
|
||||
};
|
||||
}
|
10
src/dawnopengl/display/mesh/CMakeLists.txt
Normal file
10
src/dawnopengl/display/mesh/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# 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
|
||||
Mesh.cpp
|
||||
)
|
257
src/dawnopengl/display/mesh/Mesh.cpp
Normal file
257
src/dawnopengl/display/mesh/Mesh.cpp
Normal file
@ -0,0 +1,257 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "error/assert.hpp"
|
||||
#include "error/assertgl.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void Mesh::createBuffers(
|
||||
const int32_t verticeCount,
|
||||
const int32_t indiceCount
|
||||
) {
|
||||
assertTrue(verticeCount > 0, "Vertice count must be greater than zero.");
|
||||
assertTrue(indiceCount > 0, "Indice count must be greater than zero.");
|
||||
|
||||
// Can we re-use the buffers?
|
||||
if(
|
||||
verticeCount <= this->verticeCount &&
|
||||
indiceCount <= this->indiceCount
|
||||
) return;
|
||||
|
||||
this->disposeBuffers();
|
||||
|
||||
this->verticeCount = verticeCount;
|
||||
this->indiceCount = indiceCount;
|
||||
|
||||
auto sizePos = sizeof(glm::vec3) * verticeCount;
|
||||
auto sizeInds = sizeof(int32_t) * indiceCount;
|
||||
auto sizeCoords = sizeof(glm::vec2) * verticeCount;
|
||||
|
||||
// Generate vertex array, I don't think I need to do this tbh.
|
||||
glGenVertexArrays(1, &this->vertexArray);
|
||||
assertNoGLError();
|
||||
glBindVertexArray(this->vertexArray);
|
||||
assertNoGLError();
|
||||
|
||||
// Create some buffers, one for the vertex data, one for the indices
|
||||
GLuint buffer[2];
|
||||
glGenBuffers(2, buffer);
|
||||
assertNoGLError();
|
||||
this->vertexBuffer = buffer[0];
|
||||
if(this->vertexBuffer < 0) assertUnreachable("Can't make vertex buffer");
|
||||
this->indexBuffer = buffer[1];
|
||||
if(this->indexBuffer < 0) assertUnreachable("Can't make index buffer");
|
||||
|
||||
// Buffer an empty set of data then buffer each component
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferData(GL_ARRAY_BUFFER, sizePos+sizeCoords, 0, GL_DYNAMIC_DRAW);
|
||||
assertNoGLError();
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeInds, 0, GL_DYNAMIC_DRAW);
|
||||
assertNoGLError();
|
||||
|
||||
// Setup the attrib pointers
|
||||
size_t offset = 0;
|
||||
glVertexAttribPointer(
|
||||
0, sizeof(glm::vec3) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(0);
|
||||
assertNoGLError();
|
||||
|
||||
offset += sizePos;
|
||||
glVertexAttribPointer(
|
||||
1, sizeof(glm::vec2) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(1);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::disposeBuffers() {
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
assertNoGLError();
|
||||
|
||||
if(this->vertexBuffer != -1) {
|
||||
glDeleteBuffers(1, &this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
this->vertexBuffer = -1;
|
||||
this->verticeCount = -1;
|
||||
}
|
||||
|
||||
if(this->indexBuffer != -1) {
|
||||
glDeleteBuffers(1, &this->indexBuffer);
|
||||
assertNoGLError();
|
||||
this->indexBuffer = -1;
|
||||
this->indiceCount = -1;
|
||||
}
|
||||
|
||||
if(this->vertexArray) {
|
||||
glDeleteVertexArrays(1, &this->vertexArray);
|
||||
assertNoGLError();
|
||||
this->vertexArray = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Mesh::bufferPositions(
|
||||
const int32_t pos,
|
||||
const glm::vec3 positions[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(positions, "Positions cannot be null");
|
||||
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
|
||||
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
sizeof(glm::vec3) * pos,
|
||||
sizeof(glm::vec3) * len,
|
||||
(void*)positions
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::bufferCoordinates(
|
||||
const int32_t pos,
|
||||
const glm::vec2 coordinates[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(coordinates, "Coordinates cannot be null");
|
||||
assertTrue(pos >= 0 && pos < verticeCount, "Position must be within range");
|
||||
assertTrue(pos+len <= verticeCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
auto offsetCoordinates = (
|
||||
(sizeof(glm::vec3) * this->verticeCount) +
|
||||
(sizeof(glm::vec2) * pos)
|
||||
);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ARRAY_BUFFER,
|
||||
offsetCoordinates,
|
||||
sizeof(glm::vec2) * len,
|
||||
(void*)coordinates
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::bufferIndices(
|
||||
const int32_t pos,
|
||||
const int32_t indices[],
|
||||
const int32_t len
|
||||
) {
|
||||
assertNotNull(indices, "Indices cannot be null");
|
||||
assertTrue(pos >= 0 && pos < indiceCount, "Position must be within range");
|
||||
assertTrue(pos+len <= indiceCount, "Position + Length must be within range");
|
||||
assertTrue(len > 0, "Length must be greater than zero");
|
||||
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
assertNoGLError();
|
||||
glBufferSubData(
|
||||
GL_ELEMENT_ARRAY_BUFFER,
|
||||
sizeof(int32_t) * pos,
|
||||
sizeof(int32_t) * len,
|
||||
(void*)indices
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
void Mesh::draw(
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t start,
|
||||
const int32_t count
|
||||
) {
|
||||
if(
|
||||
count == 0 ||
|
||||
this->vertexBuffer == -1 ||
|
||||
this->indexBuffer == -1
|
||||
) return;
|
||||
|
||||
int32_t drawCount = count;
|
||||
if(count == -1) drawCount = this->indiceCount;
|
||||
|
||||
// Re-Bind the buffers
|
||||
glBindVertexArray(this->vertexArray);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
|
||||
assertNoGLError();
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
|
||||
assertNoGLError();
|
||||
|
||||
// Re-Calculate the attrib pointers.
|
||||
size_t offset = 0;
|
||||
glVertexAttribPointer(
|
||||
0, sizeof(glm::vec3) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(0);
|
||||
assertNoGLError();
|
||||
|
||||
offset += sizeof(glm::vec3) * this->verticeCount;
|
||||
glVertexAttribPointer(
|
||||
1, sizeof(glm::vec2) / sizeof(float_t),
|
||||
GL_FLOAT, GL_FALSE,
|
||||
0, (void *)offset
|
||||
);
|
||||
assertNoGLError();
|
||||
glEnableVertexAttribArray(1);
|
||||
assertNoGLError();
|
||||
|
||||
GLuint glDrawMode;
|
||||
switch(drawMode) {
|
||||
case MeshDrawMode::TRIANGLES:
|
||||
glDrawMode = GL_TRIANGLES;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::TRIANGLE_STRIP:
|
||||
glDrawMode = GL_TRIANGLE_STRIP;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::TRIANGLE_FAN:
|
||||
glDrawMode = GL_TRIANGLE_FAN;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::LINES:
|
||||
glDrawMode = GL_LINES;
|
||||
break;
|
||||
|
||||
case MeshDrawMode::POINTS:
|
||||
glDrawMode = GL_POINTS;
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported draw mode");
|
||||
}
|
||||
|
||||
// Render the elements.
|
||||
glDrawElements(
|
||||
glDrawMode,
|
||||
drawCount,
|
||||
GL_UNSIGNED_INT,
|
||||
(void *)(sizeof(int32_t) * start)
|
||||
);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
Mesh::~Mesh() {
|
||||
this->disposeBuffers();
|
||||
}
|
51
src/dawnopengl/display/mesh/Mesh.hpp
Normal file
51
src/dawnopengl/display/mesh/Mesh.hpp
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/mesh/IMesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Mesh : public IMesh {
|
||||
protected:
|
||||
GLuint vertexBuffer = -1;
|
||||
GLuint indexBuffer = -1;
|
||||
GLuint vertexArray = -1;
|
||||
|
||||
public:
|
||||
void createBuffers(
|
||||
const int32_t verticeCount,
|
||||
const int32_t indiceCount
|
||||
) override;
|
||||
|
||||
void disposeBuffers() override;
|
||||
|
||||
void bufferPositions(
|
||||
const int32_t pos,
|
||||
const glm::vec3 positions[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void bufferCoordinates(
|
||||
const int32_t pos,
|
||||
const glm::vec2 coordinates[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void bufferIndices(
|
||||
const int32_t pos,
|
||||
const int32_t indices[],
|
||||
const int32_t len
|
||||
) override;
|
||||
|
||||
void draw(
|
||||
const enum MeshDrawMode drawMode,
|
||||
const int32_t start,
|
||||
const int32_t count
|
||||
) override;
|
||||
|
||||
~Mesh();
|
||||
};
|
||||
}
|
13
src/dawnopengl/display/shader/CMakeLists.txt
Normal file
13
src/dawnopengl/display/shader/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# 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
|
||||
Shader.cpp
|
||||
ShaderStage.cpp
|
||||
SimpleTexturedShader.cpp
|
||||
ShaderParameter.cpp
|
||||
)
|
8
src/dawnopengl/display/shader/Shader.cpp
Normal file
8
src/dawnopengl/display/shader/Shader.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Shader.hpp"
|
||||
|
||||
using namespace Dawn;
|
238
src/dawnopengl/display/shader/Shader.hpp
Normal file
238
src/dawnopengl/display/shader/Shader.hpp
Normal file
@ -0,0 +1,238 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/ShaderStage.hpp"
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "error/assertgl.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
#include "ShaderStructure.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef GLuint shadertexturebinding_t;
|
||||
|
||||
enum class ShaderOpenGLVariant {
|
||||
GLSL_330_CORE
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class Shader : public IShader<T> {
|
||||
private:
|
||||
std::vector<std::shared_ptr<ShaderStage>> stages;
|
||||
std::vector<struct ShaderParameter> parameters;
|
||||
std::vector<struct IShaderStructure> structures;
|
||||
enum ShaderOpenGLVariant variant;
|
||||
|
||||
GLuint shaderProgram = -1;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Overridable function to get the stages for the shader.
|
||||
*
|
||||
* @param variant The variant of the shader to use.
|
||||
* @param rel The relative data to use.
|
||||
* @param stages The stages to add to.
|
||||
* @param parameters The parameters to add to.
|
||||
* @param structures The structures to add to.
|
||||
*/
|
||||
virtual void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const T *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Initializes the shader, this needs to be called before the shader can
|
||||
* be used.
|
||||
*/
|
||||
void init() override {
|
||||
// Determine which kind of OpenGL shader to use.
|
||||
variant = ShaderOpenGLVariant::GLSL_330_CORE;
|
||||
|
||||
// Now get the stages
|
||||
T dummy;
|
||||
this->getStages(
|
||||
variant,
|
||||
&dummy,
|
||||
stages,
|
||||
parameters,
|
||||
structures
|
||||
);
|
||||
|
||||
// Create the shader program
|
||||
shaderProgram = glCreateProgram();
|
||||
assertNoGLError();
|
||||
|
||||
// Attach all the stages
|
||||
for(auto stage : stages) {
|
||||
glAttachShader(shaderProgram, stage->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Link and verify the program
|
||||
glLinkProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
|
||||
GLint status;
|
||||
glGetProgramiv(shaderProgram, GL_LINK_STATUS, &status);
|
||||
assertNoGLError();
|
||||
assertTrue(status == GL_TRUE, "Failed to link shader program.");
|
||||
|
||||
// Map parameters correctly.
|
||||
std::for_each(
|
||||
parameters.begin(),
|
||||
parameters.end(),
|
||||
[&](struct ShaderParameter ¶m) {
|
||||
// Correct offset
|
||||
param.offset = param.offset - (size_t)(&dummy);
|
||||
param.location = glGetUniformLocation(
|
||||
shaderProgram,
|
||||
param.name.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
param.location != -1,
|
||||
"Failed to get location for parameter %s.",
|
||||
param.name.c_str()
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Map structures
|
||||
std::for_each(
|
||||
structures.begin(),
|
||||
structures.end(),
|
||||
[&](struct IShaderStructure &structure) {
|
||||
structure.offset = structure.offset - (size_t)(&dummy);
|
||||
structure.location = glGetUniformBlockIndex(
|
||||
shaderProgram,
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
assertNoGLError();
|
||||
assertTrue(
|
||||
structure.location != -1,
|
||||
"Failed to get location for structure %s.",
|
||||
structure.structureName.c_str()
|
||||
);
|
||||
|
||||
// Create the buffer
|
||||
glGenBuffers(1, &structure.buffer);
|
||||
}
|
||||
);
|
||||
|
||||
this->bind();
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds the shader as the current one, does not upload any data, somewhat
|
||||
* relies on something else uploading the data.
|
||||
*/
|
||||
void bind() override {
|
||||
glUseProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
/**
|
||||
* Uploads the data to the GPU.
|
||||
*/
|
||||
void upload() override {
|
||||
switch(this->variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
for(auto param : parameters) {
|
||||
void *value = (void*)(
|
||||
((size_t)&this->data) + param.offset
|
||||
);
|
||||
|
||||
switch(param.type) {
|
||||
case ShaderParameterType::MAT4: {
|
||||
glm::mat4 *matrix = (glm::mat4 *)value;
|
||||
if(param.count != 1) {
|
||||
assertUnreachable("I haven't implemented multiple mat4s");
|
||||
}
|
||||
glUniformMatrix4fv(
|
||||
param.location, 1, GL_FALSE, glm::value_ptr(*matrix)
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::COLOR: {
|
||||
auto color = (Color *)value;
|
||||
glUniform4fv(
|
||||
param.location,
|
||||
param.count,
|
||||
(GLfloat*)value
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::BOOLEAN: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
case ShaderParameterType::TEXTURE: {
|
||||
glUniform1iv(param.location, param.count, (GLint*)value);
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
assertUnreachable("Unsupported ShaderParameterType");
|
||||
}
|
||||
}
|
||||
|
||||
assertNoGLError();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Upload structures
|
||||
for(auto structure : structures) {
|
||||
switch(structure.structureType) {
|
||||
case ShaderOpenGLStructureType::STD140: {
|
||||
// Upload the data
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBindBufferBase(GL_UNIFORM_BUFFER, structure.location, structure.buffer);
|
||||
assertNoGLError();
|
||||
glBufferData(
|
||||
GL_UNIFORM_BUFFER,
|
||||
structure.size * structure.count,
|
||||
(void*)((size_t)&this->data + (size_t)structure.offset),
|
||||
GL_STATIC_DRAW
|
||||
);
|
||||
assertNoGLError();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLStructureType");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Shader() {
|
||||
// Delete the structures
|
||||
for(auto structure : structures) {
|
||||
assertTrue(structure.buffer != -1, "Invalid buffer.");
|
||||
glDeleteBuffers(1, &structure.buffer);
|
||||
assertNoGLError();
|
||||
}
|
||||
|
||||
// Delete the shader program
|
||||
glDeleteProgram(shaderProgram);
|
||||
assertNoGLError();
|
||||
}
|
||||
};
|
||||
}
|
20
src/dawnopengl/display/shader/ShaderParameter.cpp
Normal file
20
src/dawnopengl/display/shader/ShaderParameter.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "ShaderParameter.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderParameter::ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count
|
||||
) {
|
||||
this->name = name;
|
||||
this->offset = (size_t)offset;
|
||||
this->type = type;
|
||||
this->count = count;
|
||||
}
|
33
src/dawnopengl/display/shader/ShaderParameter.hpp
Normal file
33
src/dawnopengl/display/shader/ShaderParameter.hpp
Normal file
@ -0,0 +1,33 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/IShader.hpp"
|
||||
#include "dawnopengl.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct ShaderParameter {
|
||||
std::string name;
|
||||
size_t offset;
|
||||
enum ShaderParameterType type;
|
||||
size_t count;
|
||||
GLint location = -1;
|
||||
|
||||
/**
|
||||
* Construct a new shader parameter.
|
||||
*
|
||||
* @param name Name of the parameter within the shader.
|
||||
* @param offset Offset, relative to the structure of the data.
|
||||
* @param type Type of the parameter.
|
||||
* @param count How many elements in the array (if multiple).
|
||||
*/
|
||||
ShaderParameter(
|
||||
const std::string &name,
|
||||
const void *offset,
|
||||
const enum ShaderParameterType type,
|
||||
const size_t count = 1
|
||||
);
|
||||
};
|
||||
}
|
69
src/dawnopengl/display/shader/ShaderStage.cpp
Normal file
69
src/dawnopengl/display/shader/ShaderStage.cpp
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "error/assertgl.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "ShaderStage.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ShaderStage::ShaderStage(
|
||||
const enum ShaderStageType type,
|
||||
const std::string source
|
||||
) : IShaderStage(type) {
|
||||
// Get OpenGL Shader Type
|
||||
GLenum shaderType;
|
||||
switch(this->type) {
|
||||
case ShaderStageType::VERTEX:
|
||||
shaderType = GL_VERTEX_SHADER;
|
||||
break;
|
||||
|
||||
case ShaderStageType::FRAGMENT:
|
||||
shaderType = GL_FRAGMENT_SHADER;
|
||||
break;
|
||||
|
||||
// case ShaderStageType::COMPUTE:
|
||||
// shaderType = GL_COMPUTE;
|
||||
// break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown ShaderStageType");
|
||||
}
|
||||
|
||||
// Initialize the shader
|
||||
this->id = glCreateShader(shaderType);
|
||||
assertNoGLError();
|
||||
|
||||
// Compile the shader
|
||||
auto cSource = source.c_str();
|
||||
glShaderSource(this->id, 1, &cSource, NULL);
|
||||
assertNoGLError();
|
||||
glCompileShader(this->id);
|
||||
assertNoGLError();
|
||||
|
||||
// Validate
|
||||
GLint status;
|
||||
glGetShaderiv(this->id, GL_COMPILE_STATUS, &status);
|
||||
assertNoGLError();
|
||||
|
||||
if(!status) {
|
||||
// Failed to compile
|
||||
GLint logLength;
|
||||
glGetShaderiv(this->id, GL_INFO_LOG_LENGTH, &logLength);
|
||||
assertNoGLError();
|
||||
|
||||
GLchar *log = new GLchar[logLength];
|
||||
glGetShaderInfoLog(this->id, logLength, NULL, log);
|
||||
assertNoGLError();
|
||||
assertUnreachable("Failed to compile shader stage %i:\n%s", type, log);
|
||||
}
|
||||
}
|
||||
|
||||
ShaderStage::~ShaderStage() {
|
||||
if(this->id != -1) {
|
||||
glDeleteShader(this->id);
|
||||
assertNoGLError();
|
||||
}
|
||||
}
|
28
src/dawnopengl/display/shader/ShaderStage.hpp
Normal file
28
src/dawnopengl/display/shader/ShaderStage.hpp
Normal file
@ -0,0 +1,28 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnopengl.hpp"
|
||||
#include "display/shader/IShaderStage.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ShaderStage : public IShaderStage {
|
||||
public:
|
||||
GLuint id = -1;
|
||||
|
||||
/**
|
||||
* Constructs a new ShaderStage.
|
||||
*
|
||||
* @param type The type of shader this is.
|
||||
* @param source The source code to compile.
|
||||
*/
|
||||
ShaderStage(const enum ShaderStageType type, const std::string source);
|
||||
|
||||
/**
|
||||
* Disposes of the shader stage.
|
||||
*/
|
||||
~ShaderStage();
|
||||
};
|
||||
}
|
95
src/dawnopengl/display/shader/ShaderStructure.hpp
Normal file
95
src/dawnopengl/display/shader/ShaderStructure.hpp
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma ocne
|
||||
#include "display/shader/ShaderParameter.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum class ShaderOpenGLStructureType {
|
||||
STD140
|
||||
};
|
||||
|
||||
struct IShaderStructure {
|
||||
std::string structureName;
|
||||
size_t offset;
|
||||
enum ShaderOpenGLStructureType structureType;
|
||||
size_t size;
|
||||
size_t count;
|
||||
std::vector<struct ShaderParameter> parameters;
|
||||
GLint location = -1;
|
||||
GLuint buffer = -1;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ShaderStructure final : public IShaderStructure {
|
||||
public:
|
||||
/**
|
||||
* Constructs a new shader structure. Shader structures allow for larger
|
||||
* amounts/volumes of data to be passed to the shader in a single call.
|
||||
* Ideally I wouldn't really need this as I wanted the entire shader to
|
||||
* basically be a single large structure, but OpenGL doesn't support that
|
||||
* so I have to do this instead.
|
||||
*
|
||||
* @param structureName Structure name within the shader.
|
||||
* @param offset Offset, within the data structure, that this structure
|
||||
* starts at.
|
||||
* @param structureType The type of structure data format to use.
|
||||
* @param getParameters A callback that, when invoked, will populate the
|
||||
* parameters vector with the parameters for this
|
||||
* structure.
|
||||
*/
|
||||
ShaderStructure(
|
||||
const std::string &structureName,
|
||||
const void *offset,
|
||||
const enum ShaderOpenGLStructureType structureType,
|
||||
std::function<
|
||||
void(const T&, std::vector<struct ShaderParameter>&)
|
||||
> getParameters,
|
||||
size_t count = 1
|
||||
) {
|
||||
this->structureName = structureName;
|
||||
this->offset = (size_t)offset;
|
||||
this->structureType = structureType;
|
||||
this->size = sizeof(T);
|
||||
this->count = count;
|
||||
this->parameters = std::vector<struct ShaderParameter>();
|
||||
|
||||
T dummy;
|
||||
getParameters(dummy, this->parameters);
|
||||
|
||||
// Update offsets.
|
||||
auto itParams = this->parameters.begin();
|
||||
while(itParams != this->parameters.end()) {
|
||||
struct ShaderParameter ¶m = *itParams;
|
||||
param.offset -= (size_t)(&dummy);
|
||||
|
||||
// Check for non-aligned OpenGL structures.
|
||||
if(param.offset % sizeof(glm::vec4) != 0) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
if(
|
||||
itParams == (this->parameters.end() - 1) &&
|
||||
count > 1 &&
|
||||
(sizeof(T) % sizeof(glm::vec4)) != 0
|
||||
) {
|
||||
assertUnreachable(
|
||||
"%s%s%s",
|
||||
"Non-aligned OpenGL structure detected on last element in array structure on param ",
|
||||
param.name.c_str(),
|
||||
"!\nEnsure you have padded correctly."
|
||||
);
|
||||
}
|
||||
|
||||
++itParams;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
100
src/dawnopengl/display/shader/SimpleTexturedShader.cpp
Normal file
100
src/dawnopengl/display/shader/SimpleTexturedShader.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/shader/SimpleTexturedShader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void SimpleTexturedShader::getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) {
|
||||
// Stages
|
||||
std::shared_ptr<ShaderStage> vertex;
|
||||
std::shared_ptr<ShaderStage> fragment;
|
||||
|
||||
switch(variant) {
|
||||
case ShaderOpenGLVariant::GLSL_330_CORE:
|
||||
vertex = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::VERTEX,
|
||||
"#version 330 core\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n"
|
||||
"uniform mat4 u_Projection;\n"
|
||||
"uniform mat4 u_View;\n"
|
||||
"uniform mat4 u_Model;\n"
|
||||
"out vec2 o_TextCoord;\n"
|
||||
"void main() {\n"
|
||||
"gl_Position = u_Projection * u_View * u_Model * vec4(aPos, 1.0);\n"
|
||||
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
|
||||
"}"
|
||||
);
|
||||
|
||||
fragment = std::make_shared<ShaderStage>(
|
||||
ShaderStageType::FRAGMENT,
|
||||
"#version 330 core\n"
|
||||
"in vec2 o_TextCoord;\n"
|
||||
"out vec4 o_Color;\n"
|
||||
"uniform vec4 u_Color;\n"
|
||||
"uniform bool u_HasTexture;\n"
|
||||
"uniform sampler2D u_Texture;\n"
|
||||
"void main() {\n"
|
||||
"if(u_HasTexture) {\n"
|
||||
"o_Color = texture(u_Texture, o_TextCoord) * u_Color;\n"
|
||||
"} else {\n"
|
||||
"o_Color = u_Color;"
|
||||
"}\n"
|
||||
"}\n"
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported ShaderOpenGLVariant");
|
||||
}
|
||||
|
||||
// Add stages
|
||||
stages.push_back(vertex);
|
||||
stages.push_back(fragment);
|
||||
|
||||
// Parameters
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Projection",
|
||||
&rel->projection,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_View",
|
||||
&rel->view,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Model",
|
||||
&rel->model,
|
||||
ShaderParameterType::MAT4
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Color",
|
||||
&rel->color,
|
||||
ShaderParameterType::COLOR
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_HasTexture",
|
||||
&rel->hasTexture,
|
||||
ShaderParameterType::BOOLEAN
|
||||
));
|
||||
|
||||
parameters.push_back(ShaderParameter(
|
||||
"u_Texture",
|
||||
&rel->texture,
|
||||
ShaderParameterType::TEXTURE
|
||||
));
|
||||
}
|
29
src/dawnopengl/display/shader/SimpleTexturedShader.hpp
Normal file
29
src/dawnopengl/display/shader/SimpleTexturedShader.hpp
Normal file
@ -0,0 +1,29 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/shader/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct SimpleTexturedShaderData {
|
||||
glm::mat4 projection;
|
||||
glm::mat4 view;
|
||||
glm::mat4 model;
|
||||
struct Color color = COLOR_WHITE;
|
||||
bool hasTexture = false;
|
||||
shadertexturebinding_t texture = 0;
|
||||
};
|
||||
|
||||
class SimpleTexturedShader : public Shader<SimpleTexturedShaderData> {
|
||||
protected:
|
||||
void getStages(
|
||||
const enum ShaderOpenGLVariant variant,
|
||||
const struct SimpleTexturedShaderData *rel,
|
||||
std::vector<std::shared_ptr<ShaderStage>> &stages,
|
||||
std::vector<struct ShaderParameter> ¶meters,
|
||||
std::vector<struct IShaderStructure> &structures
|
||||
) override;
|
||||
};
|
||||
}
|
11
src/dawnopengl/error/CMakeLists.txt
Normal file
11
src/dawnopengl/error/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
assertgl.cpp
|
||||
erroropengl.cpp
|
||||
)
|
59
src/dawnopengl/error/assertgl.cpp
Normal file
59
src/dawnopengl/error/assertgl.cpp
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "assertgl.hpp"
|
||||
#include "error/assert.hpp"
|
||||
#include "dawnopengl.hpp"
|
||||
|
||||
void assertNotGLErrorCheck(const char *file, int32_t line) {
|
||||
GLenum errorCode;
|
||||
std::string fileString = file;
|
||||
std::string error = "GL Error";
|
||||
int32_t errorCount = 0;
|
||||
|
||||
while((errorCode = glGetError()) != GL_NO_ERROR) {
|
||||
errorCount++;
|
||||
switch (errorCode) {
|
||||
case GL_INVALID_ENUM:
|
||||
error += "\nINVALID_ENUM";
|
||||
break;
|
||||
|
||||
case GL_INVALID_VALUE:
|
||||
error += "\nINVALID_VALUE";
|
||||
break;
|
||||
|
||||
case GL_INVALID_OPERATION:
|
||||
error += "\nINVALID_OPERATION";
|
||||
break;
|
||||
|
||||
case GL_STACK_OVERFLOW:
|
||||
error += "\nSTACK_OVERFLOW";
|
||||
break;
|
||||
|
||||
case GL_STACK_UNDERFLOW:
|
||||
error += "\nSTACK_UNDERFLOW";
|
||||
break;
|
||||
|
||||
case GL_OUT_OF_MEMORY:
|
||||
error += "\nOUT_OF_MEMORY";
|
||||
break;
|
||||
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
error += "\nINVALID_FRAMEBUFFER_OPERATION";
|
||||
break;
|
||||
|
||||
default:
|
||||
error += "\nUNKNOWN GL ERROR ERROR";
|
||||
break;
|
||||
}
|
||||
|
||||
error += " (" + std::to_string(errorCode) + ")";
|
||||
}
|
||||
|
||||
if(errorCount != 0) {
|
||||
error += "\n" + std::string(file) + " (" + std::to_string(line) + ")";
|
||||
assertUnreachable(error.c_str());
|
||||
}
|
||||
}
|
20
src/dawnopengl/error/assertgl.hpp
Normal file
20
src/dawnopengl/error/assertgl.hpp
Normal file
@ -0,0 +1,20 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
|
||||
/**
|
||||
* Asserts that there are no OpenGL errors.
|
||||
*
|
||||
* @param file The file the assertion is being made in.
|
||||
* @param line The line the assertion is being made in.
|
||||
*/
|
||||
void assertNotGLErrorCheck(const char *file, int32_t line);
|
||||
|
||||
/**
|
||||
* Asserts that there are no OpenGL errors.
|
||||
*/
|
||||
#define assertNoGLError() assertNotGLErrorCheck(__FILE__, __LINE__)
|
56
src/dawnopengl/error/erroropengl.cpp
Normal file
56
src/dawnopengl/error/erroropengl.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "erroropengl.hpp"
|
||||
|
||||
void errorCheckOpenGL() {
|
||||
std::stringstream buffer;
|
||||
GLenum errorCode;
|
||||
int32_t errorCount = 0;
|
||||
|
||||
while((errorCode = glGetError()) != GL_NO_ERROR) {
|
||||
errorCount++;
|
||||
|
||||
switch (errorCode) {
|
||||
case GL_INVALID_ENUM:
|
||||
buffer << "INVALID_ENUM" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_INVALID_VALUE:
|
||||
buffer << "INVALID_VALUE" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_INVALID_OPERATION:
|
||||
buffer << "INVALID_OPERATION" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_INVALID_FRAMEBUFFER_OPERATION:
|
||||
buffer << "INVALID_FRAMEBUFFER_OPERATION" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_OUT_OF_MEMORY:
|
||||
buffer << "OUT_OF_MEMORY" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_STACK_UNDERFLOW:
|
||||
buffer << "STACK_UNDERFLOW" << std::endl;
|
||||
break;
|
||||
|
||||
case GL_STACK_OVERFLOW:
|
||||
buffer << "STACK_OVERFLOW" << std::endl;
|
||||
break;
|
||||
|
||||
default:
|
||||
buffer << "UNKNOWN" << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
buffer << "(Error Code: " << errorCode << ")" << std::endl;
|
||||
}
|
||||
|
||||
if(errorCount > 0) {
|
||||
throw std::runtime_error("OpenGL Error(s) Found: " + buffer.str());
|
||||
}
|
||||
}
|
13
src/dawnopengl/error/erroropengl.hpp
Normal file
13
src/dawnopengl/error/erroropengl.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawn.hpp"
|
||||
#include "dawnopengl.hpp"
|
||||
|
||||
/**
|
||||
* Checks for OpenGL errors. Throws an exception if an error is found.
|
||||
*/
|
||||
void errorCheckOpenGL();
|
21
src/dawnrpg/CMakeLists.txt
Normal file
21
src/dawnrpg/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Libraries
|
||||
|
||||
# Includes
|
||||
target_include_directories(${DAWN_TARGET_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(scene)
|
10
src/dawnrpg/scene/CMakeLists.txt
Normal file
10
src/dawnrpg/scene/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2024 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
RPGScene.cpp
|
||||
)
|
8
src/dawnrpg/scene/RPGScene.cpp
Normal file
8
src/dawnrpg/scene/RPGScene.cpp
Normal file
@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RPGScene.hpp"
|
||||
|
||||
using namespace Dawn;
|
13
src/dawnrpg/scene/RPGScene.hpp
Normal file
13
src/dawnrpg/scene/RPGScene.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
// Copyright (c) 2024 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/Scene.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RPGScene : public Scene {
|
||||
public:
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user