This commit is contained in:
2025-07-17 09:06:30 -05:00
parent bfd1ac6953
commit 6d89abf64e
278 changed files with 1 additions and 21034 deletions

View File

@@ -1,34 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Build Project
add_executable(${DAWN_TARGET_NAME})
# Validate game project includes the target name
if(NOT DEFINED DAWN_TARGET_NAME)
message(FATAL_ERROR "You need to define a target name")
endif()
# Add in base library
add_subdirectory(dawn)
add_subdirectory(dawnrpg)
if(DAWN_ENABLE_PHYSICS)
add_subdirectory(dawnphysics)
endif()
# Host Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
${DAWN_BUILD_HOST_LIBS}
)
# Compile support targets
add_subdirectory(dawnglfw)
add_subdirectory(dawnopengl)
add_subdirectory(dawnlinux)
# Compress the game assets.
add_dependencies(${DAWN_TARGET_NAME} dawnassets)

View File

@@ -1,48 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Libraries
target_link_libraries(${DAWN_TARGET_NAME}
PUBLIC
archive_static
glm::glm
nlohmann_json::nlohmann_json
freetype
slang
)
# Includes
target_include_directories(${DAWN_TARGET_NAME}
PUBLIC
${CMAKE_CURRENT_LIST_DIR}
)
# Definitions
target_compile_definitions(${DAWN_TARGET_NAME}
PUBLIC
DAWN_DEBUG_SHADERS=$<BOOL:${DAWN_DEBUG_SHADERS}>
)
# Subdirs
add_subdirectory(assert)
add_subdirectory(asset)
add_subdirectory(audio)
add_subdirectory(component)
add_subdirectory(display)
add_subdirectory(environment)
add_subdirectory(game)
add_subdirectory(locale)
add_subdirectory(save)
add_subdirectory(scene)
add_subdirectory(settings)
add_subdirectory(time)
add_subdirectory(util)
# Assets
tool_copy(en en.json)
tool_copy(simpleTexturedShader shaders/simple-textured.slang)
add_dependencies(${DAWN_TARGET_NAME} dawnassets)

View File

@@ -1,9 +0,0 @@
# 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
)

View File

@@ -1,35 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "assert.hpp"
void assertTrueImplement(
const char *file,
const int32_t line,
const char *func,
const bool_t result,
const char *message,
...
) {
if(result) return;
// Print file info.
fprintf(
stderr,
"Assert failed in %s:%i :: %s\n",
file,
line,
func
);
va_list argptr;
va_start(argptr, message);
vfprintf(stderr, message, argptr);
va_end(argptr);
fprintf(stderr, "\n");
throw std::runtime_error("Assert failed.");
}

View File

@@ -1,126 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "util/Flag.hpp"
/**
* Asserts that a given statement must evaluate to true or the assertion fails
* and the game will close semi-gracefully.
*
* @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.
*/
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 map does not have 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 assertMapNotHasKey(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( \
Flag::isOff(value, flag), __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( \
Flag::isOn(value, flag), __VA_ARGS__ \
)
/**
* Asserts that the current code is deprecated and should not be used anymore.
* @deprecated
*/
#define assertDeprecated(...) assertUnreachable(__VA_ARGS__)

View File

@@ -1,230 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "AssetDataLoader.hpp"
#include "util/Math.hpp"
using namespace Dawn;
ssize_t assetDataLoaderArchiveRead(
struct archive *archive,
void *d,
const void **buffer
) {
assertNotNull(archive, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
assertNotNull(buffer, "Buffer is NULL!");
AssetDataLoader *loader = (AssetDataLoader*)d;
*buffer = loader->buffer;
size_t read = fread(
loader->buffer, 1, ASSET_LOADER_BUFFER_SIZE, loader->assetArchiveFile
);
if(ferror(loader->assetArchiveFile)) return ARCHIVE_FATAL;
return read;
}
int64_t assetDataLoaderArchiveSeek(
struct archive *archive,
void *d,
int64_t offset,
int32_t whence
) {
assertNotNull(archive, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
assertTrue(offset > 0, "Offset must be greater than 0!");
AssetDataLoader *loader = (AssetDataLoader*)d;
int32_t ret = fseek(loader->assetArchiveFile, offset, whence);
assertTrue(ret == 0, "Failed to seek!");
return ftell(loader->assetArchiveFile);
}
int32_t assetDataLoaderArchiveOpen(struct archive *a, void *d) {
assertNotNull(a, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
AssetDataLoader *loader = (AssetDataLoader*)d;
int32_t ret = fseek(loader->assetArchiveFile, 0, SEEK_SET);
assertTrue(ret == 0, "Failed to seek to start of file!");
return ARCHIVE_OK;
}
int32_t assetDataLoaderArchiveClose(struct archive *a, void *d) {
assertNotNull(a, "Archive is NULL!");
assertNotNull(d, "Data is NULL!");
return assetDataLoaderArchiveOpen(a, d);
}
// // // // // // // // // // // // // // // // // // // // // // // // // // //
AssetDataLoader::AssetDataLoader(const std::string &fileName) :
fileName(fileName)
{
assertTrue(
fileName.size() > 0,
"IAssetDataLoader::IAssetDataLoader: fileName must be greater than 0"
);
}
size_t AssetDataLoader::getSize() {
assertTrue(this->assetArchiveEntry != nullptr, "Entry is NULL!");
assertTrue(
archive_entry_size_is_set(assetArchiveEntry),
"Entry size is not set!"
);
return archive_entry_size(assetArchiveEntry);
}
size_t AssetDataLoader::getPosition() {
assertNotNull(this->assetArchiveFile, "File is not open!");
return this->position;
}
std::string AssetDataLoader::getEntireContentsAsString() {
if(!this->isOpen()) {
this->open();
} else {
this->rewind();
}
std::string buffer;
buffer.resize(this->getSize());
this->read((uint8_t*)buffer.data(), buffer.size());
this->close();
return buffer;
}
bool_t AssetDataLoader::isOpen() {
return this->assetArchive != nullptr;
}
void AssetDataLoader::open() {
assertNull(this->assetArchiveFile, "File is already open");
assertNull(this->assetArchive, "Archive is already open");
assertNull(this->assetArchiveEntry, "Entry is already open");
this->assetArchiveFile = this->openAssetArchiveFile();
assertNotNull(this->assetArchiveFile, "Failed to open archive file!");
// Open archive reader
assetArchive = archive_read_new();
assertNotNull(assetArchive, "Failed to create archive reader");
// Set up the reader
archive_read_support_format_tar(assetArchive);
// Open reader
archive_read_set_open_callback(assetArchive, &assetDataLoaderArchiveOpen);
archive_read_set_read_callback(assetArchive, &assetDataLoaderArchiveRead);
archive_read_set_seek_callback(assetArchive, &assetDataLoaderArchiveSeek);
archive_read_set_close_callback(assetArchive, &assetDataLoaderArchiveClose);
archive_read_set_callback_data(assetArchive, this);
int32_t ret = archive_read_open1(assetArchive);
assertTrue(ret == ARCHIVE_OK, "Failed to open archive!");
position = 0;
// Iterate over each file to find the one for this asset loader.
while(archive_read_next_header(assetArchive, &assetArchiveEntry)==ARCHIVE_OK){
const char_t *headerFile = (char_t*)archive_entry_pathname(
assetArchiveEntry
);
if(std::string(headerFile) == this->fileName) return;
int32_t ret = archive_read_data_skip(assetArchive);
assertTrue(ret == ARCHIVE_OK, "Failed to skip data!");
}
assertUnreachable("Failed to find file!");
}
int32_t AssetDataLoader::close() {
assertNotNull(this->assetArchiveFile, "File is NULL");
assertNotNull(this->assetArchive, "Archive is NULL!");
assertNotNull(this->assetArchiveEntry, "Entry is NULL!");
// Close the archive
int32_t ret = archive_read_free(this->assetArchive);
assertTrue(ret == ARCHIVE_OK, "Failed to close archive!");
this->assetArchive = nullptr;
this->assetArchiveEntry = nullptr;
// Close the file
int32_t res = fclose(this->assetArchiveFile);
this->assetArchiveFile = nullptr;
return res;
}
size_t AssetDataLoader::read(uint8_t *buffer, const size_t &size) {
assertNotNull(buffer, "Buffer is NULL!");
assertTrue(size > 0, "Size must be greater than 0!");
assertNotNull(this->assetArchive, "Archive is NULL!");
assertNotNull(this->assetArchiveEntry, "Entry is NULL!");
ssize_t read = archive_read_data(this->assetArchive, buffer, size);
this->position += read;
if(read == ARCHIVE_FATAL) {
assertUnreachable(archive_error_string(this->assetArchive));
}
assertTrue(read != ARCHIVE_RETRY, "Failed to read data (RETRY)!");
assertTrue(read != ARCHIVE_WARN, "Failed to read data (WARN)!");
return read;
}
size_t AssetDataLoader::readUntil(
uint8_t *buffer,
const size_t maxSize,
const char_t delimiter
) {
size_t totalRead = this->read(buffer, maxSize);
size_t i = 0;
while(i < totalRead) {
if(buffer[i] == delimiter) break;
i++;
}
buffer[i++] = '\0';
return i;
}
size_t AssetDataLoader::skip(const size_t &n) {
assertTrue(n >= 0, "Byte count must be greater than 0.");
assertTrue(n < (this->getSize() - this->position), "Cannot skip past EOF!");
uint8_t dumpBuffer[ASSET_LOADER_BUFFER_SIZE];
size_t skipped = 0;
size_t n2, n3, n4;
n4 = n;
while(n4 != 0) {
n2 = Math::min<size_t>(n4, ASSET_LOADER_BUFFER_SIZE);
n3 = this->read(dumpBuffer, n2);
assertTrue(n3 == n2, "Failed to skip bytes!");
n4 -= n3;
}
return skipped;
}
size_t AssetDataLoader::setPosition(const size_t position) {
assertTrue(position >= 0, "Position must be greater than or equal to 0");
this->rewind();
return this->skip(position);
}
void AssetDataLoader::rewind() {
assertTrue(this->isOpen(), "Asset is not open!");
if(this->position == 0) return;
// TODO: See if I can optimize this
this->close();
this->open();
}
AssetDataLoader::~AssetDataLoader() {
if(this->assetArchiveFile != nullptr) this->close();
}

View File

@@ -1,180 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
extern "C" {
#include <archive.h>
#include <archive_entry.h>
}
#define ASSET_LOADER_BUFFER_SIZE 32768
/**
* Method invoked by the libarchive internals to read bytes from the archive
* file pointer.
*
* @param archive Archive requesting the read.
* @param data Data pointer passed to the archive.
* @param buffer Pointer to where the buffer pointer should be stored.
* @return Count of bytes read.
*/
ssize_t assetDataLoaderArchiveRead(
struct archive *archive,
void *data,
const void **buffer
);
/**
* Method invoked by the libarchive internals to seek the archive file pointer.
*
* @param archive Archive requesting the seek.
* @param data Data pointer passed to the archive.
* @param offset Offset to seek to.
* @param whence Whence to seek from.
* @return The new offset.
*/
int64_t assetDataLoaderArchiveSeek(
struct archive *archive,
void *data,
int64_t offset,
int32_t whence
);
/**
* Method invoked by the libarchive internals to open the archive file pointer.
*
* @param archive Archive requesting the open.
* @param data Data pointer passed to the archive.
* @return 0 if success, otherwise for failure.
*/
int32_t assetDataLoaderArchiveOpen(struct archive *a, void *data);
/**
* Method invoked by the libarchive internals to close the archive file pointer.
*
* @param archive Archive requesting the close.
* @param data Data pointer passed to the archive.
* @return 0 if success, otherwise for failure.
*/
int32_t assetDataLoaderArchiveClose(struct archive *a, void *data);
namespace Dawn {
class AssetDataLoader {
protected:
struct archive *assetArchive = nullptr;
struct archive_entry *assetArchiveEntry = nullptr;
size_t position;
std::string fileName;
public:
uint8_t buffer[ASSET_LOADER_BUFFER_SIZE];
FILE *assetArchiveFile = nullptr;
/**
* Unimplemented method intended to be implemented by the platform that
* will be used to request a File pointer to the asset.
*
* @return Pointer to the opened asset archive.
*/
FILE * openAssetArchiveFile();
/**
* Create a new asset loader. Asset Loaders can be used to load data from
* a file in a myriad of ways.
*
* @param fileName File name of the asset that is to be loaded.
*/
AssetDataLoader(const std::string &filename);
/**
* Get the size of the asset.
* @return The size of the asset in bytes.
*/
size_t getSize();
/**
* Returns the current position of the read head.
*
* @return The current read head position.
*/
size_t getPosition();
/**
* Get the entire contents of the asset as a string.
*
* @return The entire contents of the asset as a string.
*/
std::string getEntireContentsAsString();
/**
* Check if the asset is open.
*
* @return True if the asset is open, otherwise false.
*/
bool_t isOpen();
/**
* Platform-centric method to open a file buffer to an asset.
*/
void open();
/**
* Closes the previously ppened asset.
* @return 0 if successful, otherwise false.
*/
int32_t close();
/**
* Read bytes from buffer.
* @param buffer Pointer to a ubyte array to buffer data into.
* @param size Length of the data buffer (How many bytes to read).
* @return The count of bytes read.
*/
size_t read(uint8_t *buffer, const size_t &size);
/**
* Reads bytes from the buffer until a given delimiter is found. Returned
* position will be the index of the delimiter within the buffer.
*
* @param buffer Buffer to read into.
* @param maxSize Maximum size of the buffer.
* @param delimiter Delimiter to read until.
* @return The count of bytes read (including null terminator)
*/
size_t readUntil(
uint8_t *buffer,
const size_t maxSize,
const char_t delimiter
);
/**
* Skips the read head forward to a given position.
*
* @param n Count of bytes to progress the read head by.
* @return Count of bytes progressed.
*/
size_t skip(const size_t &n);
/**
* Rewind the read head to the beginning of the file.
*/
void rewind();
/**
* Sets the absolute position of the read head within the buffer of the
* file.
*
* @param absolutePosition Absolute position to set the read head to.
*/
size_t setPosition(const size_t absolutePosition);
/**
* Cleanup the asset loader.
*/
virtual ~AssetDataLoader();
};
}

View File

@@ -1,42 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "AssetLoader.hpp"
#include "assert/assert.hpp"
#include "asset/AssetManager.hpp"
using namespace Dawn;
const std::string AssetLoader::ASSET_TYPE = "unknown";
AssetLoader::AssetLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
assetManager(assetManager),
name(name)
{
assertNotNull(assetManager, "AssetManager cannot be null");
assertTrue(name.size() > 0, "Name cannot be empty");
std::cout << "Loading: " << name << std::endl;
}
std::shared_ptr<AssetManager> AssetLoader::getAssetManager() {
auto am = this->assetManager.lock();
assertNotNull(am, "AssetManager is null");
return am;
}
void AssetLoader::loadImmediately() {
while(!this->loaded) {
this->getAssetManager()->update();
}
}
AssetLoader::~AssetLoader() {
this->loaded = false;
std::cout << "Unloading: " << name << std::endl;
}

View File

@@ -1,71 +0,0 @@
// 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 {
class AssetManager;
class AssetLoader {
private:
std::weak_ptr<AssetManager> assetManager;
public:
std::string typetest;
const static std::string ASSET_TYPE;
const std::string name;
bool_t loaded = false;
/**
* Create an abstract Asset object.
*
* @param name Name of the asset.
*/
AssetLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
/**
* Virtual function that will be called by the asset manager on a
* synchronous basis. This will only trigger if the blocks are false and
* the loaded is also false.
*/
virtual void updateSync() = 0;
/**
* Virtual function called by the asset manager asynchronously every tick.
* This will only trigger if blocks are false and the loaded state is also
* false.
*/
virtual void updateAsync() = 0;
/**
* Returns the asset type.
*
* @return The asset type.
*/
virtual std::string getAssetType() const = 0;
/**
* Returns the asset manager.
*
* @return The asset manager.
*/
std::shared_ptr<AssetManager> getAssetManager();
/**
* Load the asset immediately, this is blocking on the main thread.
*/
void loadImmediately();
/**
* Dispose the asset item.
*/
virtual ~AssetLoader();
};
}

View File

@@ -1,77 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "AssetManager.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
void AssetManager::init(const std::shared_ptr<Game> &game) {
assertNotNull(game, "Game is NULL?");
this->game = game;
}
void AssetManager::update() {
auto copyPendingAssets = pendingAssetLoaders;
auto itPending = copyPendingAssets.begin();
while(itPending != copyPendingAssets.end()) {
auto loader = *itPending;
loader->updateSync();
loader->updateAsync();
loader->updateSync();
if(!loader->loaded) {
++itPending;
continue;
}
finishedAssetLoaders.push_back(loader);
auto it = std::find(
pendingAssetLoaders.begin(),
pendingAssetLoaders.end(),
loader
);
assertTrue(it != pendingAssetLoaders.end(), "Loader not found?");
pendingAssetLoaders.erase(it);
++itPending;
}
}
void AssetManager::remove(const std::shared_ptr<AssetLoader> loader) {
for(
auto it = pendingAssetLoaders.begin();
it != pendingAssetLoaders.end();
it++
) {
if(*it != loader) continue;
pendingAssetLoaders.erase(it);
return;
}
for(
auto it = finishedAssetLoaders.begin();
it != finishedAssetLoaders.end();
it++
) {
if(it->lock() != loader) continue;
finishedAssetLoaders.erase(it);
return;
}
}
bool_t AssetManager::isEverythingLoaded() {
return pendingAssetLoaders.size() == 0;
}
std::shared_ptr<Game> AssetManager::getGame() {
auto g = game.lock();
assertNotNull(g, "Game is NULL?");
return g;
}
AssetManager::~AssetManager() {
}

View File

@@ -1,114 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "asset/AssetLoader.hpp"
namespace Dawn {
class Game;
class AssetManager final : public std::enable_shared_from_this<AssetManager> {
private:
std::weak_ptr<Game> game;
std::vector<std::shared_ptr<AssetLoader>> pendingAssetLoaders;
std::vector<std::weak_ptr<AssetLoader>> finishedAssetLoaders;
/**
* Returns an existing asset loader if it exists.
*
* @param filename The filename of the asset to get.
* @return The asset loader if it exists, otherwise nullptr.
*/
template<class T>
std::shared_ptr<T> getExisting(const std::string &filename) {
for(auto &loader : pendingAssetLoaders) {
if(loader->name != filename) continue;
if(loader->getAssetType() != T::ASSET_TYPE) continue;
return std::static_pointer_cast<T>(loader);
}
for(auto &wLoader : finishedAssetLoaders) {
auto loader = wLoader.lock();
if(!loader) continue;
if(loader->name != filename) continue;
if(loader->getAssetType() != T::ASSET_TYPE) continue;
return std::static_pointer_cast<T>(loader);
}
return nullptr;
}
/**
* Removes an existing asset loader if it exists.
*
* @param filename The filename of the asset to remove.
*/
void removeExisting(const std::string &filename);
public:
/**
* Initializes this asset manager so it can begin accepting assets.
*
* @param game Game context that this asset manager is attached to.
*/
void init(const std::shared_ptr<Game> &game);
/**
* Updates the asset manager.
*/
void update();
/**
* Returns whether the asset manager has loaded all of the currently
* managed assets.
*
* @return True if all assets have been loaded.
*/
bool_t isEverythingLoaded();
/**
* Returns the asset loader for the given asset.
*
* @param filename The filename of the asset to get.
* @return The asset loader for the given asset.
*/
template<class T>
std::shared_ptr<T> get(const std::string &filename) {
auto existing = this->getExisting<T>(filename);
if(existing) return existing;
std::shared_ptr<T> loader = std::make_shared<T>(
shared_from_this(),
filename
);
pendingAssetLoaders.push_back(
std::static_pointer_cast<AssetLoader>(loader)
);
return loader;
}
/**
* Returns the game context that this asset manager is attached to.
*
* @return The game context.
*/
std::shared_ptr<Game> getGame();
/**
* Removes the given asset loader from the asset manager, assumes that
* nothing else needs to access it and any dangling shared_ptrs will have
* to remain in memory.
*
* @param loader The asset loader to remove.
*/
void remove(const std::shared_ptr<AssetLoader> loader);
/**
* Dispose the asset manager, and all attached assets.
*/
~AssetManager();
};
}

View File

@@ -1,15 +0,0 @@
# Copyright (c) 2022 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
AssetLoader.cpp
AssetDataLoader.cpp
AssetManager.cpp
)
# Subdirs
add_subdirectory(loader)

View File

@@ -1,17 +0,0 @@
# Copyright (c) 2022 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
TextureLoader.cpp
JSONLoader.cpp
TrueTypeLoader.cpp
ShaderLoader.cpp
StringLoader.cpp
)
# Subdirs
add_subdirectory(scene)

View File

@@ -1,43 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "JSONLoader.hpp"
using namespace Dawn;
const std::string JSONLoader::ASSET_TYPE = "json";
JSONLoader::JSONLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
loader(name),
state(JSONLoaderState::INITIAL)
{
this->typetest = this->getAssetType();
}
void JSONLoader::updateAsync() {
if(this->state != JSONLoaderState::INITIAL) return;
this->state = JSONLoaderState::LOADING_JSON;
std::string jsonContents = loader.getEntireContentsAsString();
this->data = json::parse(jsonContents);
this->state = JSONLoaderState::DONE;
this->loaded = true;
}
void JSONLoader::updateSync() {
}
std::string JSONLoader::getAssetType() const {
return JSONLoader::ASSET_TYPE;
}
JSONLoader::~JSONLoader() {
}

View File

@@ -1,37 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
namespace Dawn {
enum class JSONLoaderState {
INITIAL,
LOADING_JSON,
DONE
};
class JSONLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum JSONLoaderState state;
public:
const static std::string ASSET_TYPE;
json data;
JSONLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
~JSONLoader();
};
}

View File

@@ -1,60 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "ShaderLoader.hpp"
#include "assert/assert.hpp"
#include "asset/AssetManager.hpp"
#include "game/Game.hpp"
using namespace Dawn;
const std::string ShaderLoader::ASSET_TYPE = "shader";
ShaderLoader::ShaderLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
state(ShaderLoaderState::INITIAL),
shader(std::make_shared<ShaderProgram>())
{
}
void ShaderLoader::updateAsync() {
}
void ShaderLoader::updateSync() {
if(state != ShaderLoaderState::INITIAL) return;
this->state = ShaderLoaderState::LOADING;
assertFalse(loaded, "ShaderLoader already loaded.");
// Shorthand.
auto sm = this->getAssetManager()->getGame()->shaderManager;
// Load the shader string
Slang::ComPtr<IBlob> diagnostics;
auto module = sm->session->loadModule(
this->name.c_str(),
diagnostics.writeRef()
);
shader->init(module, sm->session);
// Finished loading.
this->state = ShaderLoaderState::LOADED;
this->loaded = true;
}
std::string ShaderLoader::getAssetType() const {
return ShaderLoader::ASSET_TYPE;
}
std::shared_ptr<ShaderProgram> ShaderLoader::getShader() {
assertNotNull(shader, "ShaderLoader shader is null.");
return shader;
}
ShaderLoader::~ShaderLoader() {
shader = nullptr;
}

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
#include "display/shader/ShaderManager.hpp"
#include "display/shader/ShaderProgram.hpp"
namespace Dawn {
enum class ShaderLoaderState {
INITIAL,
LOADING,
LOADED
};
class ShaderLoader : public AssetLoader {
protected:
enum ShaderLoaderState state;
std::shared_ptr<ShaderProgram> shader;
public:
const static std::string ASSET_TYPE;
ShaderLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
/**
* Retreives the shader program for this loader.
*
* @return The shader program that this loader is managing.
*/
std::shared_ptr<ShaderProgram> getShader();
~ShaderLoader();
};
}

View File

@@ -1,38 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "StringLoader.hpp"
using namespace Dawn;
const std::string StringLoader::ASSET_TYPE = "string";
StringLoader::StringLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
loader(name),
state(StringLoaderState::INITIAL)
{
}
void StringLoader::updateSync() {
}
void StringLoader::updateAsync() {
if(this->state != StringLoaderState::INITIAL) return;
this->state = StringLoaderState::LOADING_STRING;
this->data = this->loader.getEntireContentsAsString();
this->state = StringLoaderState::DONE;
this->loaded = true;
}
std::string StringLoader::getAssetType() const {
return StringLoader::ASSET_TYPE;
}
StringLoader::~StringLoader() {
}

View File

@@ -1,36 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
namespace Dawn {
enum class StringLoaderState {
INITIAL,
LOADING_STRING,
DONE
};
class StringLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum StringLoaderState state;
public:
const static std::string ASSET_TYPE;
std::string data;
StringLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
~StringLoader();
};
}

View File

@@ -1,157 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TextureLoader.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
const std::string TextureLoader::ASSET_TYPE = "texture";
TextureLoader::TextureLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
loader(name),
state(TextureLoaderLoadState::INITIAL)
{
this->typetest = this->getAssetType();
texture = std::make_shared<Texture>();
}
void TextureLoader::updateAsync() {
if(this->state != TextureLoaderLoadState::INITIAL) return;
this->state = TextureLoaderLoadState::ASYNC_LOADING;
this->loader.open();
// Read in the header.
uint8_t buffer[TEXTURE_LOADER_HEADER_SIZE];
size_t pos = 0;
// Read Version
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
std::string version = std::string((char*)buffer);
assertTrue(version == "DT_2.00", "Invalid Texture Version!");
// Read Texture Width
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
width = std::stoi(std::string((char*)buffer));
assertTrue(width > 0, "Invalid Texture Width!");
// Read Texture Height
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
height = std::stoi(std::string((char*)buffer));
assertTrue(height > 0, "Invalid Texture Height!");
// Texture Format (RGBA, RGB, etc)
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFormat = std::stoi(std::string((char*)buffer));
switch(iFormat) {
case 1: format = TextureFormat::R; break;
case 2: format = TextureFormat::RG; break;
case 3: format = TextureFormat::RGB; break;
case 4: format = TextureFormat::RGBA; break;
default: assertUnreachable("Invalid Texture Format %i!", iFormat);
}
// Wrap X
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapX = std::stoi(std::string((char*)buffer));
switch(iWrapX) {
case 0: wrapX = TextureWrapMode::REPEAT; break;
case 1: wrapX = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapX = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapX = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap X %i!", iWrapX);
}
// Wrap Y
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iWrapY = std::stoi(std::string((char*)buffer));
switch(iWrapY) {
case 0: wrapY = TextureWrapMode::REPEAT; break;
case 1: wrapY = TextureWrapMode::MIRRORED_REPEAT; break;
case 2: wrapY = TextureWrapMode::CLAMP_TO_EDGE; break;
case 3: wrapY = TextureWrapMode::CLAMP_TO_BORDER; break;
default: assertUnreachable("Invalid Texture Wrap Y %i!", iWrapY);
}
// Filter Min
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMin = std::stoi(std::string((char*)buffer));
switch(iFilterMin) {
case 0: filterMin = TextureFilterMode::NEAREST; break;
case 1: filterMin = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Min %i!", iFilterMin);
}
// Filter Mag
this->loader.setPosition(pos);
pos += this->loader.readUntil(buffer, TEXTURE_LOADER_HEADER_SIZE, '|');
int32_t iFilterMag = std::stoi(std::string((char*)buffer));
switch(iFilterMag) {
case 0: filterMag = TextureFilterMode::NEAREST; break;
case 1: filterMag = TextureFilterMode::LINEAR; break;
default: assertUnreachable("Invalid Texture Filter Mag %i!", iFilterMag);
}
// Data begins here. This part is done synchronously directly to the GPU.
this->loader.setPosition(pos);
size_t bufferSize = width * height * iFormat;
data = new uint8_t[bufferSize];
assertNotNull(data, "Failed to allocate texture data!");
this->loader.read(data, bufferSize);
// Handoff to sync to buffer to GPU.
this->state = TextureLoaderLoadState::ASYNC_DONE;
}
void TextureLoader::updateSync() {
if(this->state != TextureLoaderLoadState::ASYNC_DONE) return;
this->state = TextureLoaderLoadState::SYNC_LOADING;
assertNotNull(this->texture, "Texture is null!");
assertNotNull(this->data, "Texture data is null!");
// Setup Texture
this->texture->setSize(
this->width,
this->height,
this->format,
TextureDataFormat::UNSIGNED_BYTE
);
this->texture->buffer(this->data);
// Free data buffer
delete[] this->data;
this->data = nullptr;
// Hand off and call done
this->state = TextureLoaderLoadState::SYNC_DONE;
this->loaded = true;
}
std::string TextureLoader::getAssetType() const {
return TextureLoader::ASSET_TYPE;
}
std::shared_ptr<Texture> TextureLoader::getTexture() {
return this->texture;
}
TextureLoader::~TextureLoader() {
if(this->data != nullptr) {
delete[] this->data;
this->data = nullptr;
}
this->texture = nullptr;
}

View File

@@ -1,55 +0,0 @@
// Copyright (c) 2022 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
#include "display/Texture.hpp"
#define TEXTURE_LOADER_HEADER_SIZE 256
namespace Dawn {
enum class TextureLoaderLoadState {
INITIAL,
ASYNC_LOADING,
ASYNC_DONE,
SYNC_LOADING,
SYNC_DONE
};
class TextureLoader : public AssetLoader {
protected:
AssetDataLoader loader;
enum TextureLoaderLoadState state;
uint8_t *data = nullptr;
int32_t width = -1, height = -1;
enum TextureFormat format;
enum TextureWrapMode wrapX;
enum TextureWrapMode wrapY;
enum TextureFilterMode filterMin;
enum TextureFilterMode filterMag;
std::shared_ptr<Texture> texture;
public:
const static std::string ASSET_TYPE;
TextureLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
/**
* Get the texture asset.
*
* @return Texture asset.
*/
std::shared_ptr<Texture> getTexture();
~TextureLoader();
};
}

View File

@@ -1,107 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TrueTypeLoader.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
const std::string TrueTypeLoader::ASSET_TYPE = "ttf";
TrueTypeLoader::TrueTypeLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
loader(name)
{
this->typetest = this->getAssetType();
// Init the font.
auto ret = FT_Init_FreeType(&fontLibrary);
assertTrue(ret == 0, "Failed to initialize FreeType library.");
}
void TrueTypeLoader::updateSync() {
if(state != TrueTypeLoaderState::ASYNC_DONE) return;
state = TrueTypeLoaderState::SYNC_LOADING;
// Init all the textures.
auto it = textures.begin();
while(it != textures.end()) {
auto texture = it->second.lock();
if(texture) {
texture->setFace(face);
it++;
continue;
}
it = textures.erase(it);
}
// Done
state = TrueTypeLoaderState::SYNC_DONE;
this->loaded = true;
}
void TrueTypeLoader::updateAsync() {
if(state != TrueTypeLoaderState::INITIAL) return;
state = TrueTypeLoaderState::ASYNC_LOADING;
// Load the data.
this->loader.open();
size_t size = loader.getSize();
buffer = new uint8_t[size];
// Read the data.
size_t readSize = loader.read(buffer, size);
assertTrue(readSize == size, "Failed to read all data from TrueTypeLoader.");
// Init the font.
auto ret = FT_New_Memory_Face(fontLibrary, buffer, size, 0, &face);
assertTrue(ret == 0, "Failed to load font face.");
// Now close the asset loader
loader.close();
state = TrueTypeLoaderState::ASYNC_DONE;
}
std::string TrueTypeLoader::getAssetType() const {
return TrueTypeLoader::ASSET_TYPE;
}
std::shared_ptr<TrueTypeTexture> TrueTypeLoader::getTexture(
const uint32_t fontSize
) {
// Check if we have the texture already and it hasn't gone stale.
auto it = textures.find(fontSize);
if(it != textures.end()) {
if(!it->second.expired()) return it->second.lock();
textures.erase(it);
}
// Create the texture.
auto texture = std::make_shared<TrueTypeTexture>(fontSize);
textures[fontSize] = texture;
if(this->loaded) texture->setFace(face);
return texture;
}
TrueTypeLoader::~TrueTypeLoader() {
if(
this->state == TrueTypeLoaderState::SYNC_DONE ||
this->state == TrueTypeLoaderState::SYNC_LOADING ||
this->state == TrueTypeLoaderState::ASYNC_DONE
) {
FT_Done_Face(face);
}
FT_Done_FreeType(fontLibrary);
if(buffer != nullptr) {
delete[] buffer;
buffer = nullptr;
}
}

View File

@@ -1,53 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/AssetLoader.hpp"
#include "asset/AssetDataLoader.hpp"
#include "display/font/TrueTypeTexture.hpp"
namespace Dawn {
enum class TrueTypeLoaderState {
INITIAL,
ASYNC_LOADING,
ASYNC_DONE,
SYNC_LOADING,
SYNC_DONE
};
class TrueTypeLoader : public AssetLoader {
protected:
FT_Library fontLibrary;
FT_Face face;
AssetDataLoader loader;
std::unordered_map<uint32_t, std::weak_ptr<TrueTypeTexture>> textures;
enum TrueTypeLoaderState state = TrueTypeLoaderState::INITIAL;
uint8_t *buffer = nullptr;
public:
const static std::string ASSET_TYPE;
TrueTypeLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
/**
* Returns the texture for the given font size.
*
* @param fontSize Font size to get the texture for.
* @return Texture for the given character.
*/
std::shared_ptr<TrueTypeTexture> getTexture(
const uint32_t fontSize
);
~TrueTypeLoader();
};
}

View File

@@ -1,13 +0,0 @@
# Copyright (c) 2025 Dominic Msters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
SceneLoader.cpp
LoaderForSceneItems.cpp
PrefabLoader.cpp
SceneLoadContext.cpp
)

View File

@@ -1,76 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "LoaderForSceneItems.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "asset/loader/scene/PrefabLoader.hpp"
#include "asset/loader/ShaderLoader.hpp"
using namespace Dawn;
LoaderForSceneItems::LoaderForSceneItems(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
AssetLoader(assetManager, name),
ctx(std::make_shared<SceneLoadContext>())
{
}
void LoaderForSceneItems::setupDependencies() {
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
assertNotNull(ctx, "SceneLoadContext is NULL?");
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
// Begin loading dependencies.
auto &data = this->jsonLoader->data;
if(data.contains("assets")) {
for(auto &asset : data["assets"].items()) {
auto &assetName = asset.key();
auto &assetData = asset.value();
assertTrue(assetData.contains("type"), "Asset missing type");
assertTrue(assetData.contains("path"), "Asset missing path");
auto type = assetData["type"].get<std::string>();
auto path = assetData["path"].get<std::string>();
// Is this asset already named?
if(ctx->assets.find(assetName) != ctx->assets.end()) {
// Check if path and type already the same.
auto &existing = ctx->assets[assetName];
assertTrue(
existing->name == path && existing->getAssetType() == type,
"Asset already exists with different path or type: %s",
assetName.c_str()
);
continue;
}
std::shared_ptr<AssetLoader> loader;
if(type == "texture") {
loader = getAssetManager()->get<TextureLoader>(path);
} else if(type == "json") {
loader = getAssetManager()->get<JSONLoader>(path);
} else if(type == "prefab") {
auto prefabLoader = getAssetManager()->get<PrefabLoader>(path);
prefabLoader->ctx->parent = ctx;
loader = prefabLoader;
} else if(type == "shader") {
loader = getAssetManager()->get<ShaderLoader>(path);
} else {
assertUnreachable("Unknown asset type: %s", type.c_str());
}
ctx->assets[assetName] = loader;
}
}
}
LoaderForSceneItems::~LoaderForSceneItems() {
jsonLoader = nullptr;
}

View File

@@ -1,39 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "asset/loader/JSONLoader.hpp"
#include "SceneLoadContext.hpp"
namespace Dawn {
class LoaderForSceneitems;
class LoaderForSceneItems :
public AssetLoader,
public std::enable_shared_from_this<LoaderForSceneItems>
{
protected:
std::shared_ptr<JSONLoader> jsonLoader;
/**
* Loads the dependencies into the context for the data available in
* the jsonLoader.
*/
void setupDependencies();
public:
const std::shared_ptr<SceneLoadContext> ctx;
LoaderForSceneItems(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
~LoaderForSceneItems();
friend class SceneLoader;
friend class PrefabLoader;
};
}

View File

@@ -1,69 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "PrefabLoader.hpp"
#include "SceneLoader.hpp"
#include "game/Game.hpp"
#include "assert/assert.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "scene/Scene.hpp"
#include "component/SceneComponentRegistry.hpp"
#include "util/JSON.hpp"
using namespace Dawn;
const std::string PrefabLoader::ASSET_TYPE = "prefab";
PrefabLoader::PrefabLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
LoaderForSceneItems(assetManager, name)
{
this->typetest = this->getAssetType();
}
void PrefabLoader::updateSync() {
switch(this->state) {
case PrefabLoaderState::INITIAL:
jsonLoader = getAssetManager()->get<JSONLoader>(this->name);
this->state = PrefabLoaderState::LOADING_JSON;
break;
case PrefabLoaderState::LOADING_JSON:
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
if(!this->jsonLoader->loaded) return;
this->state = PrefabLoaderState::LOADING_DEPENDENCIES;
this->ctx->data = this->jsonLoader->data;
this->setupDependencies();
break;
case PrefabLoaderState::LOADING_DEPENDENCIES:
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
// Check if all dependencies are loaded.
for(auto &asset : ctx->assets) {
if(!asset.second->loaded) return;
}
this->state = PrefabLoaderState::DEPENDENCIES_LOADED;
this->loaded = true;
break;
default:
break;
}
}
void PrefabLoader::updateAsync() {
}
std::string PrefabLoader::getAssetType() const {
return PrefabLoader::ASSET_TYPE;
}
PrefabLoader::~PrefabLoader() {
}

View File

@@ -1,39 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "LoaderForSceneItems.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
enum class PrefabLoaderState {
INITIAL,
LOADING_JSON,
LOADING_DEPENDENCIES,
DEPENDENCIES_LOADED,
DONE
};
class PrefabLoader : public LoaderForSceneItems {
protected:
PrefabLoaderState state = PrefabLoaderState::INITIAL;
std::shared_ptr<SceneItem> item;
public:
const static std::string ASSET_TYPE;
PrefabLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
~PrefabLoader();
};
}

View File

@@ -1,18 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SceneLoadContext.hpp"
using namespace Dawn;
std::shared_ptr<SceneItem> SceneLoadContext::getItem(const std::string &j) {
auto it = items.find(j);
if(it == items.end()) {
auto parent = this->parent.lock();
assertNotNull(parent, "Couldn't find item.");
return parent->getItem(j);
}
return it->second;
}

View File

@@ -1,85 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "assert/assert.hpp"
namespace Dawn {
class Scene;
class SceneItem;
class SceneComponent;
class AssetLoader;
class SceneLoadContext;
class PrefabLoader;
class LoaderForSceneItems;
class SceneLoader;
class SceneLoadContext {
private:
std::weak_ptr<SceneLoadContext> parent;
std::unordered_map<std::string, std::shared_ptr<SceneItem>> items;
std::unordered_map<std::string, std::shared_ptr<SceneComponent>> components;
std::unordered_map<std::string, std::shared_ptr<AssetLoader>> assets;
std::shared_ptr<Scene> currentScene;
std::shared_ptr<SceneItem> currentItem;
std::shared_ptr<SceneComponent> currentComponent;
public:
json data;
/**
* Gets an asset from the context.
*
* @param j Name of the asset to get.
* @return Asset from the context.
*/
template<class T>
std::shared_ptr<T> getAsset(const std::string &j) const {
auto it = assets.find(j);
if(it == assets.end()) {
auto parent = this->parent.lock();
assertNotNull(parent, "Couldn't find asset %s", j.c_str());
return parent->getAsset<T>(j);
}
auto asset = std::dynamic_pointer_cast<T>(it->second);
assertNotNull(asset, "Asset is not of the correct type.");
return asset;
}
/**
* Gets an item from the context.
*
* @param j Name of the item to get.
* @return Item from the context.
*/
std::shared_ptr<SceneItem> getItem(const std::string &j);
/**
* Gets a component from the context.
*
* @param j Name of the component to get.
* @return Component from the context.
*/
template<class T>
std::shared_ptr<T> getComponent(const std::string &j) const {
auto it = components.find(j);
if(it == components.end()) {
auto parent = this->parent.lock();
assertNotNull(parent, "Couldn't find component.");
return parent->getComponent<T>(j);
}
auto cmp = std::dynamic_pointer_cast<T>(it->second);
assertNotNull(cmp, "Component is not of the correct type.");
return cmp;
}
friend class PrefabLoader;
friend class LoaderForSceneItems;
friend class SceneLoader;
friend class SceneItem;
};
}

View File

@@ -1,126 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SceneLoader.hpp"
#include "game/Game.hpp"
#include "assert/assert.hpp"
#include "scene/Scene.hpp"
#include "util/JSON.hpp"
#include "PrefabLoader.hpp"
using namespace Dawn;
const std::string SceneLoader::ASSET_TYPE = "scene";
SceneLoader::SceneLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
) :
LoaderForSceneItems(assetManager, name),
state(SceneLoaderState::INITIAL)
{
this->typetest = this->getAssetType();
}
void SceneLoader::updateAsync() {
switch(this->state) {
case SceneLoaderState::INITIAL:
this->jsonLoader = getAssetManager()->get<JSONLoader>(this->name);
this->state = SceneLoaderState::LOADING_JSON;
break;
case SceneLoaderState::LOADING_JSON:
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
if(!this->jsonLoader->loaded) return;
this->ctx->data = this->jsonLoader->data;
this->setupDependencies();
this->state = SceneLoaderState::LOADING_DEPENDENCIES;
break;
case SceneLoaderState::LOADING_DEPENDENCIES:
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
// Check if all dependencies are loaded.
for(auto &asset : ctx->assets) {
if(!asset.second->loaded) return;
}
ctx->currentScene = std::make_shared<Scene>(
this->getAssetManager()->getGame()
);
this->state = SceneLoaderState::PENDING_STAGE;
break;
default:
break;
}
}
void SceneLoader::updateSync() {
if(this->state != SceneLoaderState::PENDING_STAGE) return;
assertNotNull(this->jsonLoader, "JSON Loader is NULL?");
assertNotNull(ctx, "SceneLoadContext is NULL?");
assertTrue(this->jsonLoader->loaded, "JSON loader not loaded?");
auto &data = this->jsonLoader->data;
if(data.contains("items")) {
// Create the scene items
for(auto &item : data["items"].items()) {
auto &itemName = item.key();
auto &itemData = item.value();
auto sceneItem = ctx->currentScene->createSceneItem();
ctx->items[itemName] = sceneItem;
}
// Add components to each scene item
for(auto &item : data["items"].items()) {
auto &itemName = item.key();
auto &itemData = item.value();
auto sceneItem = ctx->items[itemName];
sceneItem->name = itemName;
std::shared_ptr<SceneLoadContext> itemCtx;
if(itemData.contains("prefab")) {
auto prefabLoader = ctx->getAsset<PrefabLoader>(
itemData["prefab"].get<std::string>()
);
assertNotNull(prefabLoader, "Prefab loader not found");
assertTrue(prefabLoader->loaded, "Prefab loader not loaded");
assertNotNull(
prefabLoader->jsonLoader,
"Prefab JSON loader not found"
);
assertTrue(
prefabLoader->jsonLoader->loaded,
"Prefab JSON loader not loaded"
);
itemCtx = prefabLoader->ctx;
itemCtx->data = json(prefabLoader->jsonLoader->data);
itemCtx->parent = this->ctx;
JSON::mergeObjectsRecursive(itemCtx->data, itemData);
} else {
itemCtx = this->ctx;
itemCtx->data = json(itemData);
}
sceneItem->load(itemCtx);
}
}
this->jsonLoader = nullptr;
this->state = SceneLoaderState::DONE;
this->loaded = true;
}
std::string SceneLoader::getAssetType() const {
return SceneLoader::ASSET_TYPE;
}
std::shared_ptr<Scene> SceneLoader::getScene() {
assertNotNull(ctx, "Context is NULL?");
assertNotNull(ctx->currentScene, "Scene not loaded?");
return ctx->currentScene;
}
SceneLoader::~SceneLoader() {
}

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "LoaderForSceneItems.hpp"
#include "scene/Scene.hpp"
namespace Dawn {
enum class SceneLoaderState {
INITIAL,
LOADING_JSON,
LOADING_DEPENDENCIES,
PENDING_STAGE,
DONE
};
class SceneLoader : public LoaderForSceneItems {
protected:
SceneLoaderState state;
public:
const static std::string ASSET_TYPE;
SceneLoader(
const std::shared_ptr<AssetManager> assetManager,
const std::string name
);
void updateSync() override;
void updateAsync() override;
std::string getAssetType() const override;
/**
* Returns the Scene that was loaded, or nullptr if not loaded.
*
* @return The loaded scene.
*/
std::shared_ptr<Scene> getScene();
~SceneLoader();
};
}

View File

@@ -1,10 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
IAudioManager.cpp
)

View File

@@ -1,14 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IAudioManager.hpp"
using namespace Dawn;
IAudioManager::IAudioManager() {
}
IAudioManager::~IAudioManager() {
}

View File

@@ -1,32 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
class IAudioManager {
public:
/**
* Construct a new IAudioManager.
*/
IAudioManager();
/**
* Initializes the audio manager system.
*/
virtual void init() = 0;
/**
* Ticks/Update the audio manager system.
*/
virtual void update() = 0;
/**
* Deinitializes the audio manager system.
*/
virtual ~IAudioManager();
};
}

View File

@@ -1,12 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
SceneComponentRegistry.cpp
)
# Subdirs
add_subdirectory(display)

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SceneComponentRegistry.hpp"
using namespace Dawn;
std::unordered_map<
std::string,
std::function<std::shared_ptr<SceneComponent>(
const std::shared_ptr<SceneItem> &
)>
> SceneComponentRegistry::REGISTRY = {
};
std::shared_ptr<SceneComponent> SceneComponentRegistry::createComponent(
const std::string &type,
const std::shared_ptr<SceneItem> &item
) {
auto typeLower = String::toLowercase(type);
assertMapHasKey(
SceneComponentRegistry::REGISTRY,
typeLower,
"Component type not registered: %s",
type.c_str()
);
return SceneComponentRegistry::REGISTRY[typeLower](item);
}

View File

@@ -1,45 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/Scene.hpp"
#include "util/String.hpp"
namespace Dawn {
class SceneComponentRegistry final {
private:
public:
static std::unordered_map<
std::string,
std::function<std::shared_ptr<SceneComponent>(
const std::shared_ptr<SceneItem> &
)>
> REGISTRY;
template<class T>
static void reg(const std::string name) {
auto nameLower = String::toLowercase(name);
SceneComponentRegistry::REGISTRY[nameLower] = [](
const std::shared_ptr<SceneItem> &item
) {
return item->addComponent<T>();
};
}
/**
* Creates a scene component by its type name. Type names are unique and
* must be registered in order to be constructed by their string name.
*
* @param type Type name of the scene component to create.
* @param item Scene item that the component belongs to.
* @return The created scene component.
*/
static std::shared_ptr<SceneComponent> createComponent(
const std::string &type,
const std::shared_ptr<SceneItem> &item
);
};
}

View File

@@ -1,14 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Camera.cpp
MeshRenderer.cpp
)
# Subdirs
add_subdirectory(material)
add_subdirectory(mesh)

View File

@@ -1,143 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "Camera.hpp"
#include "game/Game.hpp"
using namespace Dawn;
void Camera::onInit() {
this->onResizeListener = this->getRenderTarget()->onResize.listen([&](
float_t width, float_t height
) {
this->onResize.emit(this->getRenderTarget(), width, height);
});
}
void Camera::onDispose() {
renderTarget = nullptr;
}
void Camera::load(std::shared_ptr<SceneLoadContext> ctx) {
SceneComponent::load(ctx);
if(ctx->data.contains("fov")) {
this->fov = Math::deg2rad(ctx->data["fov"].get<float_t>());
}
if(ctx->data.contains("cameraType")) {
if(
ctx->data["cameraType"] == "orthogonal" ||
ctx->data["cameraType"] == "orthographic" ||
ctx->data["cameraType"] == "ortho"
) {
this->type = CameraType::ORTHOGONAL;
} else if(ctx->data["cameraType"] == "perspective") {
this->type = CameraType::PERSPECTIVE;
} else {
assertUnreachable("Invalid Camera Type!");
}
}
if(ctx->data.contains("orthoLeft")) {
this->orthoLeft = ctx->data["orthoLeft"].get<float_t>();
} else if(ctx->data.contains("left")) {
this->orthoLeft = ctx->data["left"].get<float_t>();
}
if(ctx->data.contains("orthoRight")) {
this->orthoRight = ctx->data["orthoRight"].get<float_t>();
} else if(ctx->data.contains("right")) {
this->orthoRight = ctx->data["right"].get<float_t>();
}
if(ctx->data.contains("orthoBottom")) {
this->orthoBottom = ctx->data["orthoBottom"].get<float_t>();
} else if(ctx->data.contains("bottom")) {
this->orthoBottom = ctx->data["bottom"].get<float_t>();
}
if(ctx->data.contains("orthoTop")) {
this->orthoTop = ctx->data["orthoTop"].get<float_t>();
} else if(ctx->data.contains("top")) {
this->orthoTop = ctx->data["top"].get<float_t>();
}
if(ctx->data.contains("clipNear")) {
this->clipNear = ctx->data["clipNear"].get<float_t>();
} else if(ctx->data.contains("near")) {
this->clipNear = ctx->data["near"].get<float_t>();
} else if(ctx->data.contains("zNear")) {
this->clipNear = ctx->data["zNear"].get<float_t>();
}
if(ctx->data.contains("clipFar")) {
this->clipFar = ctx->data["clipFar"].get<float_t>();
} else if(ctx->data.contains("far")) {
this->clipFar = ctx->data["far"].get<float_t>();
} else if(ctx->data.contains("zFar")) {
this->clipFar = ctx->data["zFar"].get<float_t>();
}
}
std::shared_ptr<RenderTarget> Camera::getRenderTarget() {
if(this->renderTarget) return this->renderTarget;
return getGame()->renderHost->getBackBufferRenderTarget();
}
glm::mat4 Camera::getProjection() {
switch(this->type) {
case CameraType::ORTHOGONAL:
return glm::ortho(
(float_t)this->orthoLeft,
(float_t)this->orthoRight,
(float_t)this->orthoBottom,
(float_t)this->orthoTop,
(float_t)this->clipNear,
(float_t)this->clipFar
);
case CameraType::PERSPECTIVE:
return glm::perspective(
(float_t)this->fov,
this->getAspect(),
(float_t)this->clipNear,
(float_t)this->clipFar
);
}
assertUnreachable("Invalid Camera Type!");
return glm::mat4(1.0f);
}
float_t Camera::getAspect() {
auto rt = this->getRenderTarget();
return rt->getWidth() / rt->getHeight();
}
float_t Camera::lookAtPixelPerfect(
const glm::vec3 &position,
const glm::vec3 &look,
const float_t &scale
) {
return this->getItem()->lookAtPixelPerfect(
position,
look,
this->getRenderTarget()->getHeight(),
this->fov,
scale
);
}
void Camera::setRenderTarget(const std::shared_ptr<RenderTarget> renderTarget) {
onResizeListener();
this->renderTarget = renderTarget;
this->onResizeListener = this->getRenderTarget()->onResize.listen([&](
float_t width, float_t height
) {
this->onResize.emit(this->getRenderTarget(), width, height);
});
}

View File

@@ -1,82 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneItem.hpp"
#include "display/RenderTarget.hpp"
namespace Dawn {
enum class CameraType {
PERSPECTIVE,
ORTHOGONAL
};
class Camera final : public SceneComponent {
private:
std::shared_ptr<RenderTarget> renderTarget;
std::function<void()> onResizeListener;
public:
Event<std::shared_ptr<RenderTarget>, float_t, float_t> onResize;
float_t clipNear = 0.01f;
float_t clipFar = 1000.0f;
enum CameraType type = CameraType::PERSPECTIVE;
float_t fov = 0.785398f;
float_t orthoLeft = -1.0f;
float_t orthoRight = 1.0f;
float_t orthoBottom = -1.0f;
float_t orthoTop = 1.0f;
void onInit() override;
void onDispose() override;
void load(std::shared_ptr<SceneLoadContext> ctx) override;
/**
* Returns the aspect ratio that the camera is using. In future I may
* allow you to specify a custom ratio for stylistic reasons but for now I
* just take the ratio of the specific frame buffer.
*
* @return The aspect ratio as a ratio of w/h.
*/
float_t getAspect();
/**
* Returns the render target for this camera.
*
* @return Render target.
*/
std::shared_ptr<RenderTarget> getRenderTarget();
/**
* Returns the projection matrix for this camera.
*
* @return Projection matrix.
*/
glm::mat4 getProjection();
/**
* Shorthand for getItem()->lookAtPixelPerfect()
*
* @param position Position to look from.
* @param look Position to look at.
* @param scale Scale to use. At scale 1 then the centerest pixel is 1:1.
* @return The Z distance that was calculated.
*/
float_t lookAtPixelPerfect(
const glm::vec3 &position,
const glm::vec3 &look,
const float_t &scale = 1.0f
);
/**
* Sets the render target for this camera.
*
* @param renderTarget The render target to set.
*/
void setRenderTarget(const std::shared_ptr<RenderTarget> renderTarget);
};
}

View File

@@ -1,56 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/pass/RenderPass.hpp"
#include "display/pass/RenderPassContext.hpp"
#include "display/mesh/Mesh.hpp"
namespace Dawn {
class IRenderableComponent {
public:
/**
* Retreive the list of render passes for this component.
*
* @param ctx Context for the render pass.
* @return List of render passes.
*/
virtual std::vector<std::shared_ptr<RenderPass>> getPasses(
struct RenderPassContext &ctx
) = 0;
};
/**
* Short-hand function to create a render pass.
*
* @tparam S Shader type.
* @tparam D Shader's data type
* @param self Instance of the IRenderableComponent that is creating the pass.
* @param data Data to use for the render pass.
* @return Created render pass.
*/
// template<class S, typename D>
// std::shared_ptr<IRenderPass> createRenderPass(
// SceneComponent &self,
// const D data,
// const std::unordered_map<
// shadertexturebinding_t, std::shared_ptr<Texture>
// > textures = {},
// const std::shared_ptr<Mesh> mesh = nullptr,
// const enum MeshDrawMode drawMode = MeshDrawMode::TRIANGLES,
// int32_t indiceStart = 0,
// int32_t indiceCount = -1
// ) {
// return std::make_shared<RenderPass<S,D>>(
// self,
// data,
// textures,
// mesh,
// drawMode,
// indiceStart,
// indiceCount
// );
// }
}

View File

@@ -1,16 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "MeshRenderer.hpp"
using namespace Dawn;
void MeshRenderer::onInit() {
}
void MeshRenderer::onDispose() {
mesh = nullptr;
}

View File

@@ -1,18 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#include "scene/SceneItem.hpp"
namespace Dawn {
class MeshRenderer final : public SceneComponent {
public:
std::shared_ptr<Mesh> mesh;
void onInit() override;
void onDispose() override;
};
}

View File

@@ -1,10 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Material.cpp
SimpleTexturedMaterial.cpp
)

View File

@@ -1,16 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Material.hpp"
#include "game/Game.hpp"
using namespace Dawn;
void Material::onInit() {
this->initShaderPrograms();
}
void Material::onDispose() {
}

View File

@@ -1,27 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneComponent.hpp"
#include "component/display/IRenderableComponent.hpp"
namespace Dawn {
class Material :
public SceneComponent,
public IRenderableComponent
{
protected:
/**
* Load the shaders for this material.
*/
virtual void initShaderPrograms(
) = 0;
public:
void onInit() override;
void onDispose() override;
};
}

View File

@@ -1,95 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SimpleTexturedMaterial.hpp"
#include "util/JSON.hpp"
#include "asset/loader/TextureLoader.hpp"
#include "asset/loader/ShaderLoader.hpp"
using namespace Dawn;
void SimpleTexturedMaterial::initShaderPrograms() {
if(this->shader) return;
auto shaderFile = getGame()->assetManager->get<ShaderLoader>("shaders/simple-textured.slang");
this->shader = shaderFile->getShader();
auto structure = this->shader->getStructure();
this->data = structure->createData();
this->setColor(COLOR_WHITE);
this->setTexture(nullptr);
}
void SimpleTexturedMaterial::load(std::shared_ptr<SceneLoadContext> ctx) {
this->initShaderPrograms();
if(ctx->data.contains("color")) {
this->setColor(JSON::color(ctx->data["color"]));
}
if(ctx->data.contains("texture")) {
auto asset = ctx->getAsset<TextureLoader>(
ctx->data["texture"].get<std::string>()
);
this->setTexture(asset->getTexture());
}
}
struct Color SimpleTexturedMaterial::getColor() {
auto structure = this->shader->getStructure();
return data->get<struct Color>(structure->getOffset("color"));
}
std::shared_ptr<Texture> SimpleTexturedMaterial::getTexture() {
auto structure = this->shader->getStructure();
return data->get<std::shared_ptr<Texture>>(structure->getOffset("texture"));
}
void SimpleTexturedMaterial::setTexture(
const std::shared_ptr<Texture> texture
) {
auto structure = this->shader->getStructure();
data->set<std::shared_ptr<Texture>>(structure->getOffset("texture"), texture);
data->set<bool_t>(structure->getOffset("hasTexture"), texture != nullptr);
}
void SimpleTexturedMaterial::setColor(const struct Color color) {
auto structure = this->shader->getStructure();
data->set<struct Color>(structure->getOffset("color"), color);
}
std::vector<std::shared_ptr<RenderPass>> SimpleTexturedMaterial::getPasses(
struct RenderPassContext &ctx
) {
auto structure = this->shader->getStructure();
data->set<glm::mat4>(
structure->getOffset("projection"),
ctx.camera->getProjection()
);
data->set<glm::mat4>(
structure->getOffset("view"),
ctx.camera->getItem()->getWorldTransform()
);
data->set<glm::mat4>(
structure->getOffset("model"),
this->getItem()->getWorldTransform()
);
return {
std::make_shared<RenderPass>(
*this,
nullptr,// Get mesh automatically.
MeshDrawMode::TRIANGLES,// Move this later.
0,// Move this later.
-1,// Move this later.
this->shader,
this->data
)
};
}

View File

@@ -1,51 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "component/display/material/Material.hpp"
namespace Dawn {
class SimpleTexturedMaterial : public Material {
private:
std::shared_ptr<ShaderProgram> shader = nullptr;
std::shared_ptr<ShaderData> data;
protected:
void initShaderPrograms() override;
public:
void load(std::shared_ptr<SceneLoadContext> ctx) override;
/**
* Returns the color of this material.
*/
struct Color getColor();
/**
* Returns the texture of this material.
*
* @return The texture of this material.
*/
std::shared_ptr<Texture> getTexture();
/**
* Sets the texture of this material.
*
* @param texture The texture to set.
*/
void setTexture(const std::shared_ptr<Texture> texture);
/**
* Sets the color of this material.
*
* @param color The color to set.
*/
void setColor(const struct Color color);
std::vector<std::shared_ptr<RenderPass>> getPasses(
struct RenderPassContext &ctx
) override;
};
}

View File

@@ -1,12 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
MeshComponent.cpp
CubeMeshComponent.cpp
QuadMeshComponent.cpp
PlaneMeshComponent.cpp
)

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "CubeMeshComponent.hpp"
#include "display/mesh/CubeMesh.hpp"
#include "util/JSON.hpp"
using namespace Dawn;
void CubeMeshComponent::meshBuffer(std::shared_ptr<Mesh> mesh) {
mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
CubeMesh::buffer(
mesh,
-(size/2.0f),
size,
0, 0
);
}
void CubeMeshComponent::meshLoad(std::shared_ptr<SceneLoadContext> ctx) {
if(ctx->data.contains("size")) {
this->size = JSON::vec3(ctx->data["size"]);
} else {
this->size = glm::vec3(1.0f, 1.0f, 1.0f);
}
}
void CubeMeshComponent::setSize(const glm::vec3 &size) {
this->size = size;
this->invalidate();
}

View File

@@ -1,25 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "MeshComponent.hpp"
namespace Dawn {
class CubeMeshComponent final : public MeshComponent {
protected:
glm::vec3 size;
void meshLoad(std::shared_ptr<SceneLoadContext> ctx) override;
void meshBuffer(std::shared_ptr<Mesh> mesh) override;
public:
/**
* Sets the size of the cube.
*
* @param size Size of the cube.
*/
void setSize(const glm::vec3 &size);
};
}

View File

@@ -1,42 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "MeshComponent.hpp"
#include "scene/Scene.hpp"
#include "component/display/MeshRenderer.hpp"
using namespace Dawn;
void MeshComponent::buffer() {
if(!mesh) mesh = std::make_shared<Mesh>();
this->meshBuffer(mesh);
this->valid = true;
events.clear();
}
void MeshComponent::invalidate() {
if(!valid) return;
valid = false;
events.push_back(getScene()->onNextFrame.listen([this]() {
this->buffer();
valid = true;
}));
}
void MeshComponent::onInit() {
this->buffer();
auto renderer = getItem()->getComponent<MeshRenderer>();
if(renderer) renderer->mesh = mesh;
}
void MeshComponent::onDispose() {
mesh = nullptr;
}
void MeshComponent::load(std::shared_ptr<SceneLoadContext> ctx) {
SceneComponent::load(ctx);
if(this->mesh == nullptr) this->mesh = std::make_shared<Mesh>();
this->meshLoad(ctx);
}

View File

@@ -1,47 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "scene/SceneItem.hpp"
#include "display/mesh/Mesh.hpp"
namespace Dawn {
class MeshComponent : public SceneComponent {
private:
bool_t valid = false;
/**
* Buffers the mesh.
*/
void buffer();
protected:
/**
* Called when the mesh should be loaded.
*
* @param ctx Context to load the mesh from.
*/
virtual void meshLoad(std::shared_ptr<SceneLoadContext> ctx) = 0;
/**
* Called when the mesh should be buffered.
*
* @param mesh Mesh to buffer.
*/
virtual void meshBuffer(std::shared_ptr<Mesh> mesh) = 0;
/**
* Invalidates the mesh.
*/
void invalidate();
public:
std::shared_ptr<Mesh> mesh;
void onInit() override;
void onDispose() override;
void load(std::shared_ptr<SceneLoadContext> ctx) override;
};
}

View File

@@ -1,93 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "PlaneMeshComponent.hpp"
#include "display/mesh/PlaneMesh.hpp"
#include "util/JSON.hpp"
using namespace Dawn;
void PlaneMeshComponent::meshLoad(std::shared_ptr<SceneLoadContext> ctx) {
if(ctx->data.contains("columns")) {
columns = ctx->data["columns"];
assertTrue(columns > 0, "Columns must be greater than 0.");
} else {
columns = 10;
}
if(ctx->data.contains("rows")) {
rows = ctx->data["rows"];
assertTrue(rows > 0, "Rows must be greater than 0.");
} else {
rows = columns;
}
if(ctx->data.contains("cells")) {
assertTrue(
ctx->data["cells"].type() == json::value_t::array,
"Cells must be an array."
);
assertTrue(
ctx->data["cells"].size() == 2,
"Cells must be an array of 2 integers."
);
columns = ctx->data["cells"][0];
rows = ctx->data["cells"][1];
assertTrue(columns > 0, "Columns must be greater than 0.");
assertTrue(rows > 0, "Rows must be greater than 0.");
}
if(ctx->data.contains("planeSize")) {
planeSize = JSON::vec2(ctx->data["planeSize"]);
assertTrue(planeSize.x > 0.0f, "Plane size x must be greater than 0.");
assertTrue(planeSize.y > 0.0f, "Plane size y must be greater than 0.");
} else if(ctx->data.contains("size")) {
planeSize = JSON::vec2(ctx->data["size"]);
assertTrue(planeSize.x > 0.0f, "Size x must be greater than 0.");
assertTrue(planeSize.y > 0.0f, "Size y must be greater than 0.");
} else {
planeSize = glm::vec2(10.0f, 10.0f);
}
if(ctx->data.contains("uv")) {
uv = JSON::vec4(ctx->data["uv"]);
} else {
uv = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
}
}
void PlaneMeshComponent::meshBuffer(std::shared_ptr<Mesh> mesh) {
PlaneMesh::buffer(
mesh,
planeSize,
columns, rows,
uv
);
}
void PlaneMeshComponent::setColumns(const int32_t columns) {
assertTrue(columns > 0, "Columns must be greater than 0.");
this->columns = columns;
this->invalidate();
}
void PlaneMeshComponent::setRows(const int32_t rows) {
assertTrue(rows > 0, "Rows must be greater than 0.");
this->rows = rows;
this->invalidate();
}
void PlaneMeshComponent::setPlaneSize(const glm::vec2 &planeSize) {
assertTrue(planeSize.x > 0.0f, "Plane size x must be greater than 0.");
assertTrue(planeSize.y > 0.0f, "Plane size y must be greater than 0.");
this->planeSize = planeSize;
this->invalidate();
}
void PlaneMeshComponent::setUV(const glm::vec4 &uv) {
this->uv = uv;
this->invalidate();
}

View File

@@ -1,26 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "MeshComponent.hpp"
namespace Dawn {
class PlaneMeshComponent final : public MeshComponent {
protected:
int32_t columns;
int32_t rows;
glm::vec2 planeSize;
glm::vec4 uv;
void meshLoad(std::shared_ptr<SceneLoadContext> ctx) override;
void meshBuffer(std::shared_ptr<Mesh> mesh) override;
public:
void setColumns(const int32_t columns);
void setRows(const int32_t rows);
void setPlaneSize(const glm::vec2 &planeSize);
void setUV(const glm::vec4 &uv);
};
}

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "QuadMeshComponent.hpp"
#include "display/mesh/QuadMesh.hpp"
#include "util/JSON.hpp"
using namespace Dawn;
void QuadMeshComponent::meshBuffer(std::shared_ptr<Mesh> mesh) {
mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
QuadMesh::buffer(
mesh,
this->positions,
this->uvs,
0, 0
);
}
void QuadMeshComponent::meshLoad(std::shared_ptr<SceneLoadContext> ctx) {
if(ctx->data.contains("positions")) {
this->positions = JSON::vec4(ctx->data["positions"]);
} else {
this->positions = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
}
if(ctx->data.contains("uvs")) {
this->uvs = JSON::vec4(ctx->data["uvs"]);
} else {
this->uvs = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f);
}
}
void QuadMeshComponent::setPositions(const glm::vec4 &positions) {
this->positions = positions;
this->invalidate();
}
void QuadMeshComponent::setUVs(const glm::vec4 &uvs) {
this->uvs = uvs;
this->invalidate();
}

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "MeshComponent.hpp"
namespace Dawn {
class QuadMeshComponent final : public MeshComponent {
protected:
glm::vec4 positions;
glm::vec4 uvs;
void meshLoad(std::shared_ptr<SceneLoadContext> ctx) override;
void meshBuffer(std::shared_ptr<Mesh> mesh) override;
public:
/**
* Sets the positions of the quad.
*
* @param positions The positions of the quad.
*/
void setPositions(const glm::vec4 &positions);
/**
* Sets the UVs of the quad.
*
* @param uvs The UVs of the quad.
*/
void setUVs(const glm::vec4 &uvs);
};
}

View File

@@ -1,53 +0,0 @@
/**
* Copyright (c) 2022 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
// Static Libs
extern "C" {
// Standard Libs
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <assert.h>
#include <float.h>
#include <errno.h>
typedef bool bool_t;
typedef char char_t;
}
#include <vector>
#include <iostream>
#include <thread>
#include <map>
#include <array>
#include <memory>
#include <algorithm>
#include <sstream>
#include <string>
#include <functional>
#include <cstdarg>
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <glm/mat4x4.hpp>
// #include <glm/gtx/component_wise.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/ext/matrix_transform.hpp>
#include <glm/ext/matrix_clip_space.hpp>
#include <glm/ext/scalar_constants.hpp>
// #include <glm/gtx/intersect.hpp>
#include <glm/gtc/type_ptr.hpp>
#define GLM_ENABLE_EXPERIMENTAL 1
#include <glm/gtx/matrix_decompose.hpp>
#include <nlohmann/json.hpp>
using json = nlohmann::json;

View File

@@ -1,19 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Color.cpp
RenderPipeline.cpp
IRenderHost.cpp
)
# Subdirs
add_subdirectory(mesh)
add_subdirectory(shader)
add_subdirectory(font)
add_subdirectory(tileset)
add_subdirectory(pass)

View File

@@ -1,84 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Color.hpp"
#include "util/String.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
struct Color Color::fromString(const std::string str) {
// Convert to lowercase
auto lower = String::toLowercase(str);
if(String::includes(lower, "cornflower")) {
return COLOR_CORNFLOWER_BLUE;
} else if(String::includes(lower, "magenta")) {
return COLOR_MAGENTA;
} else if(String::includes(lower, "white")) {
return COLOR_WHITE;
} else if(String::includes(lower, "black")) {
return COLOR_BLACK;
} else if(String::includes(lower, "red")) {
return COLOR_RED;
} else if(String::includes(lower, "green")) {
return COLOR_GREEN;
} else if(String::includes(lower, "blue")) {
return COLOR_BLUE;
} else if(String::includes(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 = String::split(str, ",");
if(splitByComma.size() == 3) {
// RGB
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
1.0f
};
} else if(splitByComma.size() == 4) {
// RGBA
return {
(float_t)std::stof(splitByComma[0]),
(float_t)std::stof(splitByComma[1]),
(float_t)std::stof(splitByComma[2]),
(float_t)std::stof(splitByComma[3])
};
}
// TODO: Parse other kinds of colors
assertUnreachable("Failed to find a color match for %s", str);
return {};
}

View File

@@ -1,89 +0,0 @@
// 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
}

View File

@@ -1,14 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IRenderHost.hpp"
using namespace Dawn;
IRenderHost::IRenderHost() {
}
IRenderHost::~IRenderHost() {
}

View File

@@ -1,59 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "display/RenderTarget.hpp"
#include "display/RenderPipeline.hpp"
namespace Dawn {
class Game;
class IRenderHost {
public:
RenderPipeline renderPipeline;
/**
* Creates a render host.
*/
IRenderHost();
/**
* Initializes the render host, called by the game during the initial
* set up of the engine.
*
* @param game Game that requested the render host to initialize.
*/
virtual void init(const std::shared_ptr<Game> game) = 0;
/**
* Performs an update/tick of the render host. This would be the game
* asking the RenderHost to do the rendering.
*/
virtual void update(const std::shared_ptr<Game> game) = 0;
/**
* Overridable request from the game that asks if the RenderHost has any
* reason that it should need to close. For most libraries this would be
* whether or not the window was closed.
*
* @return True if the render host requests the game to gracefully exit.
*/
virtual bool_t isCloseRequested() = 0;
/**
* 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.
*/
virtual std::shared_ptr<RenderTarget> getBackBufferRenderTarget() = 0;
/**
* Destroys the render host.
*/
virtual ~IRenderHost();
};
}

View File

@@ -1,117 +0,0 @@
// 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:
TextureWrapMode wrapModeX = TextureWrapMode::REPEAT;
TextureWrapMode wrapModeY = TextureWrapMode::REPEAT;
TextureFilterMode filterModeMin = TextureFilterMode::NEAREST;
TextureFilterMode filterModeMag = TextureFilterMode::NEAREST;
TextureFilterMode mipMapFilterModeMin = TextureFilterMode::NEAREST;
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 TextureFormat format,
const 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() {
}
};
}

View File

@@ -1,104 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "assert/assert.hpp"
#include "RenderPipeline.hpp"
#include "game/Game.hpp"
#include "scene/Scene.hpp"
#include "component/display/Camera.hpp"
#include "component/display/IRenderableComponent.hpp"
using namespace Dawn;
RenderPipeline::RenderPipeline() {
}
void RenderPipeline::render(
const std::shared_ptr<Game> game
) {
assertNotNull(game, "Game cannot be null");
auto scene = game->getCurrentScene();
if(!scene) return;
this->renderScene(game, scene);
}
void RenderPipeline::renderScene(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
// TODO: Render Subscenes First
// Get a list of all cameras in the scene
auto cameras = scene->findComponents<Camera>();
auto backBuffer = scene->getGame()->renderHost->getBackBufferRenderTarget();
std::shared_ptr<Camera> backbufferCamera = nullptr;
for(auto camera : cameras) {
auto rt = camera->getRenderTarget();
// Is this camera the backbuffer camera?
if(rt == backBuffer) {
backbufferCamera = camera;
continue;
}
// Render scene with this camera
renderSceneCamera(game, scene, camera, rt);
}
if(backbufferCamera) {
// Render the backbuffer camera
renderSceneCamera(game, scene, backbufferCamera, backBuffer);
}
}
void RenderPipeline::renderSceneCamera(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene,
const std::shared_ptr<Camera> camera,
const std::shared_ptr<RenderTarget> renderTarget
) {
assertNotNull(game, "Game cannot be null");
assertNotNull(scene, "Scene cannot be null");
assertNotNull(camera, "Camera cannot be null");
assertNotNull(renderTarget, "RenderTarget cannot be null");
struct RenderPassContext ctx = {
game,
scene,
camera,
renderTarget
};
// Get list of renderables
std::vector<std::shared_ptr<RenderPass>> renderPasses;
auto renderables = scene->findComponents<IRenderableComponent>();
for(auto renderable : renderables) {
auto rp = renderable->getPasses(ctx);
renderPasses.insert(renderPasses.end(), rp.begin(), rp.end());
}
// TODO: Sort the render passes by priority and z-index
// TODO: Make clearing the buffers editable!
renderTarget->bind();
renderTarget->clear(
RENDER_TARGET_CLEAR_COLOR |
RENDER_TARGET_CLEAR_DEPTH
);
for(auto renderPass : renderPasses) {
renderPass->draw();
}
}
RenderPipeline::~RenderPipeline() {
}

View File

@@ -1,63 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
class Game;
class Scene;
class Camera;
class RenderTarget;
class RenderPipeline {
public:
/**
* Creates a new RenderPipeline.
*/
RenderPipeline();
/**
* Renders the game. This will render the current scene.
*
* @param game Game to render.
*/
void render(
const std::shared_ptr<Game> game
);
/**
* Renders a specific scene. This will render all cameras within the
* scene.
*
* @param game Game to render.
* @param scene Scene to render.
*/
void renderScene(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene
);
/**
* Renders a specific scene with a specific camera.
*
* @param game Game to render.
* @param scene Scene to render.
* @param camera Camera to render.
* @param renderTarget Render target to render to.
*/
void renderSceneCamera(
const std::shared_ptr<Game> game,
const std::shared_ptr<Scene> scene,
const std::shared_ptr<Camera> camera,
const std::shared_ptr<RenderTarget> renderTarget
);
/**
* Destroys the RenderPipeline.
*/
virtual ~RenderPipeline();
};
}

View File

@@ -1,71 +0,0 @@
// 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() {
}
};
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
TrueTypeTexture.cpp
)

View File

@@ -1,16 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
namespace Dawn {
struct TrueTypeCharacter {
glm::vec2 advance;
glm::vec2 size;
glm::vec2 offset;
glm::vec4 quad;
};
}

View File

@@ -1,198 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "TrueTypeTexture.hpp"
#include "assert/assert.hpp"
#include "util/Math.hpp"
#include "display/mesh/QuadMesh.hpp"
using namespace Dawn;
TrueTypeTexture::TrueTypeTexture(const uint32_t &fontSize) :
fontSize(fontSize)
{
assertTrue(fontSize > 0, "Font size cannot be zero");
texture = std::make_shared<Texture>();
}
void TrueTypeTexture::setFace(const FT_Face &face) {
this->face = face;
assertTrue(fontSize < 256, "Font size cannot be greater than 256");
// Set freetype font size prior to baking.
auto ret = FT_Set_Pixel_Sizes(face, 0, fontSize);
if(ret != 0) {
assertUnreachable("Failed to set font size %i", ret);
}
// Set the texture size
texture->setSize(
fontSize * 24,
fontSize * 24,
TextureFormat::R,
TextureDataFormat::UNSIGNED_BYTE
);
// Texture buffer
uint8_t *buffer = new uint8_t[texture->getWidth() * texture->getHeight()];
// Fill with zeros
std::memset(buffer, 0, texture->getWidth() * texture->getHeight());
size_t offset = 0;
struct TrueTypeCharacter info;
int32_t textureX = 0, textureY = 0;
int32_t rowHeight = 0;
// Character sets
std::vector<wchar_t> characterBlocks;
// Latin
for(wchar_t c = 0x0020; c < 0x007F; c++) characterBlocks.push_back(c);
// Latin-1 Supplement
for(wchar_t c = 0x00A0; c < 0x00FF; c++) characterBlocks.push_back(c);
// Latin Extended-A
for(wchar_t c = 0x0100; c < 0x017F; c++) characterBlocks.push_back(c);
// Latin Extended-B
for(wchar_t c = 0x0180; c < 0x024F; c++) characterBlocks.push_back(c);
// Hiragana
for(wchar_t c = 0x3040; c < 0x309F; c++) characterBlocks.push_back(c);
// Katakana
for(wchar_t c = 0x30A0; c < 0x30FF; c++) characterBlocks.push_back(c);
// For each character in the character set
for(wchar_t c : characterBlocks) {
// Load the character
if(FT_Load_Char(face, c, FT_LOAD_RENDER)) {
assertUnreachable("Failed to load character (1)");
}
// Store the character information
info.advance.x = (float_t)(face->glyph->advance.x >> 6);
info.advance.y = (float_t)(face->glyph->advance.y >> 6);
info.size = glm::vec2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
// Determine the texture position
if(textureX + face->glyph->bitmap.width >= texture->getWidth()) {
textureX = 0;
textureY += rowHeight + 2;// Tiny gap between rows
rowHeight = face->glyph->bitmap.rows;
} else {
rowHeight = Math::max<int32_t>(rowHeight, face->glyph->bitmap.rows);
}
// Set the quad positions
info.offset = glm::vec2(
face->glyph->bitmap_left,
-face->glyph->bitmap_top
);
info.quad = glm::vec4(
textureX,
textureY,
textureX + face->glyph->bitmap.width,
textureY + face->glyph->bitmap.rows
) / glm::vec4(
texture->getWidth(),
texture->getHeight(),
texture->getWidth(),
texture->getHeight()
);
// Store the cached character data.
this->characterData[c] = info;
// Determine pixel offset.
offset = textureX + (textureY * texture->getWidth());
assertTrue(
offset + (face->glyph->bitmap.rows * texture->getWidth()) <=
texture->getWidth() * texture->getHeight(),
"Font texture buffer overflow will occur."
);
// Buffer pixels, we have to do this one row at a time due to the
// differences in width between the glyph and the texture.
const size_t countPerRow = face->glyph->bitmap.width;
int32_t i = 0;
while(i != face->glyph->bitmap.rows) {
std::memcpy(
buffer + offset + (i * texture->getWidth()),
face->glyph->bitmap.buffer + (i * countPerRow),
countPerRow
);
i++;
}
// Increment textureX
textureX += face->glyph->bitmap.width + 2;// I add a tiny gap between chars
}
this->texture->buffer(buffer);
delete[] buffer;
}
struct TrueTypeCharacter TrueTypeTexture::getCharacterData(const wchar_t &c) {
return this->characterData[c];
}
glm::vec2 TrueTypeTexture::bufferStringToMesh(
std::shared_ptr<Mesh> mesh,
const std::wstring text,
glm::vec2 &position,
const bool_t flipY
) {
assertNotNull(mesh, "Mesh must be supplied and not null");
assertTrue(text.size() > 0, "Text must be at least one character long.");
// Create mesh buffers
mesh->createBuffers(
text.length() * QUAD_VERTICE_COUNT,
text.length() * QUAD_INDICE_COUNT
);
// Foreach char
size_t i = 0;
glm::vec2 size = { 0, 0 };
for(wchar_t c : text) {
// Get the character data
auto info = this->getCharacterData(c);
// Buffer the quad
glm::vec4 quad = glm::vec4(
position.x,
position.y,
position.x + info.size.x,
position.y + info.size.y
);
if(flipY) {
QuadMesh::buffer(
mesh,
quad,
glm::vec4(
info.quad.x,
info.quad.w,
info.quad.z,
info.quad.y
),
i * QUAD_VERTICE_COUNT,
i * QUAD_INDICE_COUNT
);
} else {
QuadMesh::buffer(
mesh,
quad,
info.quad,
i * QUAD_VERTICE_COUNT,
i * QUAD_INDICE_COUNT
);
}
position += info.advance;
size += info.advance;
i++;
}
return size;
}
TrueTypeTexture::~TrueTypeTexture() {
}

View File

@@ -1,66 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Texture.hpp"
#include "TrueTypeCharacter.hpp"
#include "display/mesh/Mesh.hpp"
#include <ft2build.h>
#include FT_FREETYPE_H
namespace Dawn {
class TrueTypeTexture final {
private:
FT_Face face;
public:
uint32_t fontSize;
std::shared_ptr<Texture> texture;
std::unordered_map<wchar_t, struct TrueTypeCharacter> characterData;
/**
* Construct a new New True Type Face Texture object
*
* @param fontSize Size of the font.
*/
TrueTypeTexture(const uint32_t &fontSize);
/**
* Sets the face for this texture.
*
* @param face Face to set.
*/
void setFace(const FT_Face &face);
/**
* Returns the character data for the given character.
*
* @param c Character to get data for.
* @return The Character data for the given character.
*/
struct TrueTypeCharacter getCharacterData(const wchar_t &c);
/**
* Buffers a string to the given mesh.
*
* @param mesh Mesh to buffer to.
* @param text Text to buffer.
* @param position Position to buffer to.
* @param flipY Whether or not to flip the Y axis.
* @return The size of the string.
*/
glm::vec2 bufferStringToMesh(
std::shared_ptr<Mesh> mesh,
const std::wstring text,
glm::vec2 &position,
const bool_t flipY = false
);
/**
* Destroys this true type face texture.
*/
~TrueTypeTexture();
};
}

View File

@@ -1,13 +0,0 @@
# Copyright (c) 2022 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
CubeMesh.cpp
QuadMesh.cpp
SphereMesh.cpp
PlaneMesh.cpp
)

View File

@@ -1,70 +0,0 @@
// 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);
}

View File

@@ -1,30 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#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
);
};
}

View File

@@ -1,102 +0,0 @@
// 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() {
}
};
}

View File

@@ -1,64 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "PlaneMesh.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
void PlaneMesh::buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec2 planeSize,
const int32_t columns,
const int32_t rows,
const glm::vec4 uv
) {
assertNotNull(mesh, "Mesh cannot be null.");
assertTrue(columns > 0, "Columns must be greater than 0.");
assertTrue(rows > 0, "Rows must be greater than 0.");
const int32_t verticeCount = (columns+1)*(rows+1) * PLANE_VERTICE_PER_SEGMENT;
const int32_t indiceCount = (columns+1)*(rows+1) * PLANE_INDICE_PER_SEGMENT;
mesh->createBuffers(verticeCount, indiceCount);
glm::vec3 positions[verticeCount];
glm::vec2 coordinates[verticeCount];
int32_t indices[indiceCount];
const glm::vec2 offset(planeSize.x / 2.0f, planeSize.y / 2.0f);
const glm::vec2 step(planeSize.x / columns, planeSize.y / rows);
for (int32_t y = 0; y <= rows; ++y) {
for (int32_t x = 0; x <= columns; ++x) {
const int32_t verticeStart = (y * (columns + 1) + x) * PLANE_VERTICE_PER_SEGMENT;
const int32_t indiceStart = (y * (columns + 1) + x) * PLANE_INDICE_PER_SEGMENT;
const float_t xPos = step.x * x - offset.x;
const float_t yPos = step.y * y - offset.y;
positions[verticeStart + 0] = glm::vec3(xPos, yPos, 0.0f);
positions[verticeStart + 1] = glm::vec3(xPos + step.x, yPos, 0.0f);
positions[verticeStart + 2] = glm::vec3(xPos, yPos + step.y, 0.0f);
positions[verticeStart + 3] = glm::vec3(xPos + step.x, yPos + step.y, 0.0f);
coordinates[verticeStart + 0] = glm::vec2(uv.x, uv.y);
coordinates[verticeStart + 1] = glm::vec2(uv.z, uv.y);
coordinates[verticeStart + 2] = glm::vec2(uv.x, uv.w);
coordinates[verticeStart + 3] = glm::vec2(uv.z, uv.w);
indices[indiceStart + 0] = verticeStart + 0;
indices[indiceStart + 1] = verticeStart + 2;
indices[indiceStart + 2] = verticeStart + 1;
indices[indiceStart + 3] = verticeStart + 1;
indices[indiceStart + 4] = verticeStart + 2;
indices[indiceStart + 5] = verticeStart + 3;
}
}
mesh->bufferPositions(0, positions, verticeCount);
mesh->bufferCoordinates(0, coordinates, verticeCount);
mesh->bufferIndices(0, indices, indiceCount);
}

View File

@@ -1,32 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#define PLANE_VERTICE_PER_SEGMENT 4
#define PLANE_INDICE_PER_SEGMENT 6
namespace Dawn {
class PlaneMesh {
public:
/**
* Buffers a plane mesh into the provided mesh.
*
* @param mesh The mesh to buffer the plane into.
* @param planeSize The size of the plane.
* @param columns The number of columns.
* @param rows The number of rows.
* @param uv The UV coordinates of the plane.
*/
static void buffer(
const std::shared_ptr<Mesh> mesh,
const glm::vec2 planeSize,
const int32_t columns,
const int32_t rows,
const glm::vec4 uv = glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)
);
};
}

View File

@@ -1,73 +0,0 @@
// 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)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
QuadMesh::bufferCoordinates(mesh, coordinates, verticeStart);
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)
};
int32_t indices[QUAD_INDICE_COUNT] = {
verticeStart, verticeStart + 1, verticeStart + 3,
verticeStart, verticeStart + 2, verticeStart + 3
};
mesh->bufferPositions(verticeStart, vertices, QUAD_VERTICE_COUNT);
QuadMesh::bufferCoordinates(mesh, coordinates, verticeStart);
mesh->bufferIndices(indiceStart, indices, QUAD_INDICE_COUNT);
}
void QuadMesh::bufferCoordinates(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 coordinates,
const int32_t verticeStart
) {
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)
};
mesh->bufferCoordinates(verticeStart, coords, QUAD_VERTICE_COUNT);
}

View File

@@ -1,68 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#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 = 0,
const int32_t indiceStart = 0,
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 = 0,
const int32_t indiceStart = 0,
const int32_t indexOffset = 0
);
/**
* Buffers quad texture coordinates to an existing mesh.
*
* @param mesh The mesh to buffer into.
* @param coordinates The coordinates to buffer.
* @param verticeStart The starting index of the vertices.
*/
static void bufferCoordinates(
const std::shared_ptr<Mesh> mesh,
const glm::vec4 coordinates,
const int32_t verticeStart = 0
);
};
}

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SphereMesh.hpp"
using namespace Dawn;
void SphereMesh::create(
std::shared_ptr<Mesh> mesh,
const float_t radius,
const int32_t segments,
const int32_t rings
) {
// Create the vertices
std::vector<glm::vec3> vertices;
for(uint32_t r = 0; r < rings; ++r) {
for(uint32_t s = 0; s < segments; ++s) {
float_t const y = sin(-M_PI_2 + M_PI * r / rings);
float_t const x = cos(2 * M_PI * s / segments) * sin(M_PI * r / rings);
float_t const z = sin(2 * M_PI * s / segments) * sin(M_PI * r / rings);
vertices.push_back(glm::vec3(x, y, z) * radius);
}
}
// Create the indices
std::vector<int32_t> indices;
for(int32_t r = 0; r < rings - 1; ++r) {
for(int32_t s = 0; s < segments - 1; ++s) {
indices.push_back(r * segments + s);
indices.push_back(r * segments + (s + 1));
indices.push_back((r + 1) * segments + (s + 1));
indices.push_back(r * segments + s);
indices.push_back((r + 1) * segments + (s + 1));
indices.push_back((r + 1) * segments + s);
}
}
mesh->createBuffers(vertices.size(), indices.size());
mesh->bufferPositions(0, vertices.data(), vertices.size());
mesh->bufferIndices(0, indices.data(), indices.size());
}

View File

@@ -1,27 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
namespace Dawn {
class SphereMesh {
public:
/**
* Creates a sphere mesh.
*
* @param mesh The mesh to buffer into.
* @param radius The radius of the sphere.
* @param segments The number of segments.
* @param rings The number of rings.
*/
static void create(
std::shared_ptr<Mesh> mesh,
const float_t radius = 1.0f,
const int32_t segments = 16,
const int32_t rings = 16
);
};
}

View File

@@ -1,9 +0,0 @@
# Copyright (c) 2024 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
target_sources(${DAWN_TARGET_NAME}
PRIVATE
RenderPass.cpp
)

View File

@@ -1,44 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "RenderPass.hpp"
#include "component/display/MeshRenderer.hpp"
using namespace Dawn;
RenderPass::RenderPass(
SceneComponent &self,
const std::shared_ptr<Mesh> mesh,
const enum MeshDrawMode drawMode,
const int32_t indiceStart,
const int32_t indiceCount,
const std::shared_ptr<ShaderProgram> shaderProgram,
const std::shared_ptr<ShaderData> shaderData
) :
mesh(mesh),
drawMode(drawMode),
indiceStart(indiceStart),
indiceCount(indiceCount),
shaderProgram(shaderProgram),
shaderData(shaderData)
{
// Need mesh?
if(!this->mesh) {
auto meshRenderer = self.getItem()->getComponent<MeshRenderer>();
if(meshRenderer) this->mesh = meshRenderer->mesh;
}
}
void RenderPass::draw() {
shaderProgram->bind();
shaderData->bind();
shaderData->upload();
mesh->draw(drawMode, indiceStart, indiceCount);
}
RenderPass::~RenderPass() {
}

View File

@@ -1,56 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/mesh/Mesh.hpp"
#include "scene/SceneComponent.hpp"
#include "display/shader/ShaderProgram.hpp"
#include "display/shader/ShaderData.hpp"
namespace Dawn {
class RenderPass {
private:
std::shared_ptr<Mesh> mesh;
std::shared_ptr<ShaderProgram> shaderProgram;
std::shared_ptr<ShaderData> shaderData;
const enum MeshDrawMode drawMode;
const int32_t indiceStart;
const int32_t indiceCount;
public:
/**
* Constructs a new RenderPass.
*
* @param self Self component instance that is creating 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.
* @param shaderProgram The shader program to use for this render pass.
* @param shaderData The shader data to use for this render pass.
*/
RenderPass(
SceneComponent &self,
const std::shared_ptr<Mesh> mesh,
const enum MeshDrawMode drawMode,
const int32_t indiceStart,
const int32_t indiceCount,
const std::shared_ptr<ShaderProgram> shaderProgram,
const std::shared_ptr<ShaderData> shaderData
);
/**
* Draws the mesh for this render pass.
*/
void draw();
/**
* Cleans up the render pass.
*/
~RenderPass();
};
}

View File

@@ -1,18 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "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;
};
}

View File

@@ -1,15 +0,0 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
ShaderManager.cpp
ShaderManagerSlangFileSystem.cpp
IShaderStage.cpp
IShaderProgram.cpp
IShaderData.cpp
ShaderStructure.cpp
)

View File

@@ -1,221 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IShaderData.hpp"
using namespace Dawn;
IShaderData::IShaderData(
const std::shared_ptr<ShaderStructure> &structure
) : structure(structure) {
data = (void *)malloc(structure->size);
}
template<>
void *IShaderData::get<void *>(const size_t offset) {
return (void *)((size_t)data + offset);
}
template<>
int8_t IShaderData::get<int8_t>(const size_t offset) {
return *(int8_t*)this->get<void*>(offset);
}
template<>
int16_t IShaderData::get<int16_t>(const size_t offset) {
return *(int16_t *)this->get<void *>(offset);
}
template<>
int32_t IShaderData::get<int32_t>(const size_t offset) {
return *(int32_t *)this->get<void *>(offset);
}
template<>
int64_t IShaderData::get<int64_t>(const size_t offset) {
return *(int64_t *)this->get<void *>(offset);
}
template<>
uint8_t IShaderData::get<uint8_t>(const size_t offset) {
return *(uint8_t *)this->get<void *>(offset);
}
template<>
uint16_t IShaderData::get<uint16_t>(const size_t offset) {
return *(uint16_t *)this->get<void *>(offset);
}
template<>
uint32_t IShaderData::get<uint32_t>(const size_t offset) {
return *(uint32_t *)this->get<void *>(offset);
}
template<>
uint64_t IShaderData::get<uint64_t>(const size_t offset) {
return *(uint64_t *)this->get<void *>(offset);
}
template<>
float_t IShaderData::get<float_t>(const size_t offset) {
return *(float_t *)this->get<void *>(offset);
}
template<>
glm::vec2 IShaderData::get<glm::vec2>(const size_t offset) {
return *(glm::vec2 *)this->get<void *>(offset);
}
template<>
glm::vec3 IShaderData::get<glm::vec3>(const size_t offset) {
return *(glm::vec3 *)this->get<void *>(offset);
}
template<>
glm::vec4 IShaderData::get<glm::vec4>(const size_t offset) {
return *(glm::vec4 *)this->get<void *>(offset);
}
template<>
glm::mat2 IShaderData::get<glm::mat2>(const size_t offset) {
return *(glm::mat2 *)this->get<void *>(offset);
}
template<>
glm::mat3 IShaderData::get<glm::mat3>(const size_t offset) {
return *(glm::mat3 *)this->get<void *>(offset);
}
template<>
glm::mat4 IShaderData::get<glm::mat4>(const size_t offset) {
return *(glm::mat4 *)this->get<void *>(offset);
}
template<>
bool_t IShaderData::get<bool_t>(const size_t offset) {
return this->get<int32_t>(offset) != 0;
}
template<>
struct Color IShaderData::get<struct Color>(const size_t offset) {
glm::vec4 v = this->get<glm::vec4>(offset);
return {
v.r,
v.g,
v.b,
v.a
};
}
void IShaderData::setRaw(
const size_t offset,
const void *value,
const size_t size
) {
memcpy(this->get<void *>(offset), value, size);
this->dirty = true;
}
template<>
void IShaderData::set<int8_t>(const size_t offset, const int8_t value) {
this->setRaw(offset, &value, sizeof(int8_t));
}
template<>
void IShaderData::set<int16_t>(const size_t offset, const int16_t value) {
this->setRaw(offset, &value, sizeof(int16_t));
}
template<>
void IShaderData::set<int32_t>(const size_t offset, const int32_t value) {
this->setRaw(offset, &value, sizeof(int32_t));
}
template<>
void IShaderData::set<int64_t>(const size_t offset, const int64_t value) {
this->setRaw(offset, &value, sizeof(int64_t));
}
template<>
void IShaderData::set<uint8_t>(const size_t offset, const uint8_t value) {
this->setRaw(offset, &value, sizeof(uint8_t));
}
template<>
void IShaderData::set<uint16_t>(const size_t offset, const uint16_t value) {
this->setRaw(offset, &value, sizeof(uint16_t));
}
template<>
void IShaderData::set<uint32_t>(const size_t offset, const uint32_t value) {
this->setRaw(offset, &value, sizeof(uint32_t));
}
template<>
void IShaderData::set<uint64_t>(const size_t offset, const uint64_t value) {
this->setRaw(offset, &value, sizeof(uint64_t));
}
template<>
void IShaderData::set<float_t>(const size_t offset, const float_t value) {
this->setRaw(offset, &value, sizeof(float_t));
}
template<>
void IShaderData::set<glm::vec2>(const size_t offset, const glm::vec2 value) {
this->setRaw(offset, &value, sizeof(glm::vec2));
}
template<>
void IShaderData::set<glm::vec3>(const size_t offset, const glm::vec3 value) {
this->setRaw(offset, &value, sizeof(glm::vec3));
}
template<>
void IShaderData::set<glm::vec4>(const size_t offset, const glm::vec4 value) {
this->setRaw(offset, &value, sizeof(glm::vec4));
}
template<>
void IShaderData::set<glm::mat2>(const size_t offset, const glm::mat2 value) {
this->setRaw(offset, &value, sizeof(glm::mat2));
}
template<>
void IShaderData::set<glm::mat3>(const size_t offset, const glm::mat3 value) {
this->setRaw(offset, &value, sizeof(glm::mat3));
}
template<>
void IShaderData::set<glm::mat4>(const size_t offset, const glm::mat4 value) {
this->setRaw(offset, &value, sizeof(glm::mat4));
}
template<>
void IShaderData::set<struct Color>(
const size_t offset,
const struct Color value
) {
this->set<glm::vec4>(offset, glm::vec4(
value.r,
value.g,
value.b,
value.a
));
}
template<>
void IShaderData::set<bool_t>(const size_t offset, const bool_t value) {
this->set<>(offset, value ? 1 : 0);
}
IShaderData::~IShaderData() {
if(data != nullptr) {
free(data);
data = nullptr;
}
}

View File

@@ -1,69 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/Texture.hpp"
#include "display/shader/ShaderStructure.hpp"
namespace Dawn {
struct IShaderData {
protected:
void *data = nullptr;
bool_t dirty = true;
public:
std::shared_ptr<ShaderStructure> structure;
/**
* Constructs the ShaderData object
*
* @param structure The structure to base this data on.
*/
IShaderData(
const std::shared_ptr<ShaderStructure> &structure
);
/**
* Gets the value out of the data by the offset.
*
* @param offset The offset to get the value from.
* @return The value at the offset.
*/
template<typename T>
T get(const size_t offset);
/**
* Gets the value out of the data by the offset.
*
* @param offset The offset to get the value from.
* @return The value at the offset.
*/
void setRaw(const size_t offset, const void *value, const size_t size);
/**
* Sets the value in the data by the offset.
*
* @param offset The offset to set the value at.
* @param value The value to set at the offset.
*/
template<typename T>
void set(const size_t offset, const T value);
/**
* Binds the buffer to the shader.
*/
virtual void bind() = 0;
/**
* Uploads the data to the GPU.
*/
virtual void upload() = 0;
/**
* Cleans up the data.
*/
virtual ~IShaderData();
};
}

View File

@@ -1,142 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IShaderProgram.hpp"
#include "assert/assert.hpp"
#if DAWN_DEBUG_SHADERS
#include <fstream>
#endif
using namespace Dawn;
void IShaderProgram::init(
IModule *module,
Slang::ComPtr<ISession> session
) {
assertNotNull(module, "Module cannot be null.");
this->module = module;
// Get list of entry points and create components
int32_t definedEntryPointCount = module->getDefinedEntryPointCount();
// +1 for module
auto components = new IComponentType*[definedEntryPointCount + 1];
int32_t componentCount = 0;
components[componentCount++] = module;// First component is module.
// Get the entry point info and append to components list.
for(auto i = 0; i < definedEntryPointCount; i++) {
auto result = module->getDefinedEntryPoint(
i,
(IEntryPoint**)(&components[componentCount++])
);
if(result != SLANG_OK) assertUnreachable("Failed to get entry point.");
}
// Create the composite component type
Slang::ComPtr<IBlob> diagnostics;
session->createCompositeComponentType(
components,
componentCount,
program.writeRef(),
diagnostics.writeRef()
);
if(diagnostics) {
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
return;
}
// Link the program.
auto result = program->link(linkedProgram.writeRef(), diagnostics.writeRef());
if(diagnostics) {
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
return;
}
// Get the layout
layout = program->getLayout();
// Create the shader program.
Slang::ComPtr<IBlob> blob;
for(auto i = 0; i < definedEntryPointCount; i++) {
// Get the code
auto result = linkedProgram->getEntryPointCode(
i,
0,
blob.writeRef(),
diagnostics.writeRef()
);
if(diagnostics) {
assertUnreachable("%s\n", (const char*) diagnostics->getBufferPointer());
}
// Get the stage information
auto entryPointReflection = layout->getEntryPointByIndex(i);
auto stage = entryPointReflection->getStage();
// Write out to file for debugging
#if DAWN_DEBUG_SHADERS
std::filesystem::path filePath = (
"debug/" +
std::string(module->getName()) +
"/" +
std::string(entryPointReflection->getName()) +
".glsl"
);
std::filesystem::create_directories(filePath.parent_path());
std::cout << "Writing shader to " << filePath << std::endl;
std::ofstream file(filePath);
file << (const char*)blob->getBufferPointer();
file.close();
#endif
// Create the shader entry
auto shaderStage = std::make_shared<ShaderStage>();
shaderStage->init(
stage,
std::string((const char*)blob->getBufferPointer())
);
// Add to the list
stages.push_back(shaderStage);
}
// Cleanup components
delete [] components;
// Reflect out the data
auto rootLayout = layout->getGlobalParamsVarLayout();
auto rootLayoutTypeLayout = rootLayout->getTypeLayout();
assertTrue(
rootLayoutTypeLayout->getKind() == TypeReflection::Kind::ConstantBuffer,
"Root layout, should and must be a constant buffer."
);
auto realRootLayout = rootLayoutTypeLayout->getElementVarLayout();
auto realRootLayoutTypeLayout = realRootLayout->getTypeLayout();
assertTrue(
realRootLayoutTypeLayout->getKind() == TypeReflection::Kind::Struct,
"Real root layout should and must be a struct."
);
// Now we can really begin parsing out the data.
structure = std::make_shared<struct ShaderStructure>(
realRootLayout->getTypeLayout(),
"root",
0
);
}
std::shared_ptr<struct ShaderStructure> IShaderProgram::getStructure() {
return structure;
}
IShaderProgram::~IShaderProgram() {
// Release the linked program
if(linkedProgram) {
linkedProgram->release();
linkedProgram = nullptr;
}
}

View File

@@ -1,59 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "display/shader/ShaderStage.hpp"
#include "display/shader/ShaderData.hpp"
namespace Dawn {
class IShaderProgram {
protected:
IModule *module;
std::vector<std::shared_ptr<ShaderStage>> stages;
ComPtr<IComponentType> program;
ComPtr<IComponentType> linkedProgram;
ProgramLayout *layout;
std::shared_ptr<struct ShaderStructure> structure;
public:
/**
* Initialize the ShaderProgram. In your render hosts' implementation
* this would initialize the shader on your GPU and ideally set the
* initial values for uniforms and objects.
*
* Provided stages will already be "initialized" (at least as far as the
* engine is concerned), and should be ready to be used. If your render
* host needs the program to be initialized prior to the stages you will
* need to modify how stages are initialized, this is by design as we are
* loading the shader code and "initializing" the stages before we create
* and initialize the program which will use and link the stages.
*
* @param module The SLANG module that was loaded.
* @param session The SLANG session that was used to load the module.
*/
virtual void init(
IModule *module,
ComPtr<ISession> session
);
/**
* Returns the structure of the shader program.
*
* @return The structure of the shader program.
*/
std::shared_ptr<struct ShaderStructure> getStructure();
/**
* Binds this shader program as the currently active shader program.
*/
virtual void bind() = 0;
/**
* Destroy the IShaderProgram2 object
*/
virtual ~IShaderProgram();
};
}

View File

@@ -1,11 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "IShaderStage.hpp"
using namespace Dawn;
IShaderStage::~IShaderStage() {
}

View File

@@ -1,33 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "slang.h"
#include "slang-com-ptr.h"
using namespace slang;
using namespace Slang;
namespace Dawn {
class IShaderStage {
public:
/**
* Initialize the IShaderEntry object
*
* @param stage The stage of the shader entry.
* @param code The code of the shader entry.
*/
virtual void init(
const SlangStage &stage,
const std::string &code
) = 0;
/**
* Destroy the IShaderEntry object
*/
virtual ~IShaderStage();
};
}

View File

@@ -1,51 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "ShaderManager.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
ShaderManager::ShaderManager() :
targetDescription(),
sessionDescription()
{
}
void ShaderManager::init(const std::shared_ptr<Game> &game) {
assertNotNull(game, "Game instance must not be null.");
this->game = game;
// Create the file system
this->fileSystem.sm = shared_from_this();
// Create the global session
createGlobalSession(globalSession.writeRef());
// Set the target description, TODO: interface
std::cout << "Need to fix GLSL hard code" << std::endl;
targetDescription.format = SLANG_GLSL;
targetDescription.profile = globalSession->findProfile("glsl_330");
// Set the session description
sessionDescription.targets = &targetDescription;
sessionDescription.targetCount = 1;
sessionDescription.searchPathCount = 0;
sessionDescription.fileSystem = &this->fileSystem;
// Create session
globalSession->createSession(sessionDescription, session.writeRef());
}
std::shared_ptr<Game> ShaderManager::getGame() {
auto game = this->game.lock();
assertNotNull(game, "Game instance must not be null.");
return game;
}
ShaderManager::~ShaderManager() {
}

View File

@@ -1,50 +0,0 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "ShaderManagerSlangFileSystem.hpp"
using namespace slang;
namespace Dawn {
class Game;
class ShaderLoader;
class ShaderManager : public std::enable_shared_from_this<ShaderManager> {
private:
std::weak_ptr<Game> game;
ShaderManagerSlangFileSystem fileSystem;
Slang::ComPtr<IGlobalSession> globalSession;
TargetDesc targetDescription;
SessionDesc sessionDescription;
Slang::ComPtr<ISession> session;
public:
/**
* Creates a new shader manager.
*/
ShaderManager();
/**
* Initializes the shader manager.
*
* @param game The game instance that the shader manager is being used in.
*/
void init(const std::shared_ptr<Game> &game);
/**
* Retreives the game instance.
*
* @return Game instance.
*/
std::shared_ptr<Game> getGame();
/**
* Disposes of all shaders.
*/
~ShaderManager();
friend class ShaderLoader;
};
}

View File

@@ -1,76 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "ShaderManagerSlangFileSystem.hpp"
#include "assert/assert.hpp"
#include "display/shader/ShaderManager.hpp"
#include "game/Game.hpp"
#include "asset/loader/StringLoader.hpp"
#include "util/String.hpp"
using namespace Dawn;
void const * ShaderManagerSlangString::getBufferPointer() {
return this->str.c_str();
}
size_t ShaderManagerSlangString::getBufferSize() {
return this->str.size();
}
SlangResult ShaderManagerSlangString::queryInterface(
SlangUUID const& uuid,
void** outObject
) {
return SLANG_E_NOT_IMPLEMENTED;
}
uint32_t ShaderManagerSlangString::addRef() {
return refs++;
}
uint32_t ShaderManagerSlangString::release() {
return refs--;
}
//
SlangResult ShaderManagerSlangFileSystem::loadFile(
const char* path,
ISlangBlob** outBlob
) {
auto shaderManager = this->sm.lock();
assertNotNull(shaderManager, "ShaderManager must not be null.");
if(!String::endsWith(path, ".slang")) return SLANG_E_NOT_FOUND;
auto loader = shaderManager->getGame()->assetManager->get<StringLoader>(path);
loader->loadImmediately();
auto blob = new ShaderManagerSlangString();
blob->str = loader->data;
*outBlob = blob;
return SLANG_OK;
}
SlangResult ShaderManagerSlangFileSystem::queryInterface(
SlangUUID const& uuid,
void** outObject
) {
return SLANG_E_NOT_IMPLEMENTED;
}
uint32_t ShaderManagerSlangFileSystem::addRef() {
return refs++;
}
uint32_t ShaderManagerSlangFileSystem::release() {
return refs--;
}
void * ShaderManagerSlangFileSystem::castAs(SlangUUID const& uuid) {
return nullptr;
}

View File

@@ -1,46 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "slang.h"
#include "slang-gfx.h"
#include "slang-com-ptr.h"
using namespace slang;
namespace Dawn {
class ShaderManager;
struct ShaderManagerSlangString : public ISlangBlob {
std::string str;
uint32_t refs = 0;
void const* getBufferPointer() override;
size_t getBufferSize() override;
SlangResult queryInterface(SlangUUID const& uuid, void** outObject) override;
uint32_t addRef() override;
uint32_t release() override;
};
struct ShaderManagerSlangFileSystem : public ISlangFileSystem {
private:
std::weak_ptr<ShaderManager> sm;
uint32_t refs = 0;
public:
SlangResult loadFile(
const char* path,
ISlangBlob** outBlob
) override;
SlangResult queryInterface(SlangUUID const& uuid, void** outObject) override;
uint32_t addRef() override;
uint32_t release() override;
void * castAs(SlangUUID const& uuid) override;
friend class ShaderManager;
};
}

View File

@@ -1,121 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "ShaderStructure.hpp"
#include "display/shader/ShaderData.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
ShaderStructure::ShaderStructure(
TypeLayoutReflection *typeLayout,
const std::string name,
const size_t start
) {
this->name = name;
this->start = start;
this->size = typeLayout->getSize();
this->alignment = typeLayout->getAlignment();
switch(typeLayout->getKind()) {
case TypeReflection::Kind::Struct: {
this->type = ShaderStructureType::STRUCT;
auto count = typeLayout->getFieldCount();
size_t offset = this->start;
for(auto i = 0; i < count; i++) {
auto field = typeLayout->getFieldByIndex(i);
auto cName = field->getName();
auto member = std::make_shared<ShaderStructure>(
field->getTypeLayout(),
cName ? std::string(cName) : "",
offset
);
offset += member->size;
this->members.push_back(member);
}
break;
}
case TypeReflection::Kind::Array: {
this->type = ShaderStructureType::ARRAY;
this->length = typeLayout->getElementCount();
auto elementType = typeLayout->getElementTypeLayout();
for(auto i = 0; i < this->length; i++) {
auto member = std::make_shared<ShaderStructure>(
elementType,
std::to_string(i),
this->start + (i * elementType->getSize())
);
this->members.push_back(member);
}
break;
}
case TypeReflection::Kind::Matrix:
case TypeReflection::Kind::Vector:
case TypeReflection::Kind::Scalar:
this->type = ShaderStructureType::VARIABLE;
break;
case TypeReflection::Kind::Resource:
switch(typeLayout->getResourceShape()) {
case SlangResourceShape::SLANG_TEXTURE_2D:
this->type = ShaderStructureType::TEXTURE2D;
break;
default:
assertUnreachable(
"Unknown resource shape: %d",
typeLayout->getResourceShape()
);
break;
}
break;
default: {
assertUnreachable("Unknown type layout kind: %d", typeLayout->getKind());
}
}
}
std::shared_ptr<ShaderStructure> ShaderStructure::getStructMember(
const std::string &name
) {
assertTrue(
this->type == ShaderStructureType::STRUCT,
"This structure is not a struct."
);
for(auto &member : this->members) {
if(member->name == name) return member;
}
assertUnreachable("Struct member not found: %s", name.c_str());
return nullptr;
}
std::shared_ptr<ShaderStructure> ShaderStructure::getArrayMember(
size_t index
) {
assertTrue(
this->type == ShaderStructureType::ARRAY,
"This structure is not an array."
);
return this->members.at(index);
}
size_t ShaderStructure::getOffset() {
return this->start;
}
size_t ShaderStructure::getOffset(const std::string &name) {
return this->getStructMember(name)->getOffset();
}
size_t ShaderStructure::getOffset(size_t index) {
return this->getArrayMember(index)->getOffset();
}
std::shared_ptr<ShaderData> ShaderStructure::createData() {
return std::make_shared<ShaderData>(shared_from_this());
}

View File

@@ -1,102 +0,0 @@
// Copyright (c) 2024 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawn.hpp"
#include "slang.h"
#include "slang-com-ptr.h"
using namespace slang;
using namespace Slang;
namespace Dawn {
class ShaderData;
enum class ShaderStructureType {
STRUCT,
ARRAY,
VARIABLE,
TEXTURE2D,
RESOURCE
};
struct ShaderStructure :
public std::enable_shared_from_this<ShaderStructure>
{
public:
std::string name;
ShaderStructureType type;
// Shared properties
size_t start;
size_t alignment;
size_t size;
// Struct properties
std::vector<std::shared_ptr<struct ShaderStructure>> members;
// Array properties
size_t length;
/**
* Constructs the ShaderStructure object
*
* @param reflection Reflection data to construct the structure from.
* @param start Offset to start at.
*/
ShaderStructure(
TypeLayoutReflection *typeLayout,
const std::string name,
const size_t start
);
/**
* Gets a member of this structure by name.
*
* @param name Name of the member to get.
* @return The member structure.
*/
std::shared_ptr<ShaderStructure> getStructMember(const std::string &name);
/**
* Gets a member of this array structure by index.
*
* @param index Index of the member to get.
* @return The member structure.
*/
std::shared_ptr<ShaderStructure> getArrayMember(size_t index);
/**
* Gets the offset of this structure.
*
* @return The offset of this structure.
*/
size_t getOffset();
/**
* Gets the offset of a member of this structure.
*
* @param name Name of the member to get.
* @return The offset of the member.
*/
size_t getOffset(const std::string &name);
/**
* Gets the offset of a member of this array structure.
*
* @param index Index of the member to get.
* @return The offset of the member.
*/
size_t getOffset(size_t index);
/**
* Creates data for a shader that matches this structure.
*
* @param name Name of the member to get.
* @return The member structure.
*/
std::shared_ptr<ShaderData> createData();
};
}

View File

@@ -1,10 +0,0 @@
# 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
TilesetGrid.cpp
)

Some files were not shown because too many files have changed in this diff Show More