Cleaned
This commit is contained in:
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
)
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -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__)
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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)
|
||||
@@ -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);
|
||||
});
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
// );
|
||||
// }
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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)
|
||||
@@ -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 {};
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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
|
||||
);
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
)
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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() {
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user