Part one - removed references and smart pointers

This commit is contained in:
2022-11-11 19:08:46 -08:00
parent e892224900
commit e6d475d170
76 changed files with 3899 additions and 3707 deletions

View File

@ -17,6 +17,7 @@ target_include_directories(${DAWN_TARGET_NAME}
) )
# Subdirs # Subdirs
add_subdirectory(assert)
add_subdirectory(asset) add_subdirectory(asset)
add_subdirectory(display) add_subdirectory(display)
add_subdirectory(input) add_subdirectory(input)

View File

@ -3,7 +3,7 @@
# This software is released under the MIT License. # This software is released under the MIT License.
# https://opensource.org/licenses/MIT # https://opensource.org/licenses/MIT
target_sources(${PROJECT_NAME} target_sources(${DAWN_TARGET_NAME}
PRIVATE PRIVATE
assert.cpp assert.cpp
) )

View File

@ -27,15 +27,11 @@
} }
void assertNotNull(const void *pointer) { void assertNotNull(const void *pointer) {
assertTrue(pointer != NULL); assertTrue(pointer != nullptr && pointer != NULL);
}
void assertNotNullptr(const void *ptr) {
assertTRue(ptr != nullptr);
} }
void assertNull(const void *pointer) { void assertNull(const void *pointer) {
assertTrue(pointer == NULL); assertTrue(pointer == NULL || pointer == nullptr);
} }
void assertDeprecated() { void assertDeprecated() {

View File

@ -13,11 +13,6 @@
#if ASSERTS_ENABLED == 0 #if ASSERTS_ENABLED == 0
static inline void assertTrue(bool_t x) {} static inline void assertTrue(bool_t x) {}
static inline void assertFalse(bool_t x) {}
static inline void assertUnreachable() {}
static inline void assertNotNull(const void *pointer) {}
static inline void assertNull(const void *pointer) {}
static inline void assertDeprecated() {}
#elif ASSERTS_ENABLED == 1 #elif ASSERTS_ENABLED == 1
@ -45,13 +40,6 @@ static inline void assertDeprecated() {}
*/ */
void assertNotNull(const void *pointer); void assertNotNull(const void *pointer);
/**
* Asserts a given pointer to not be a C++ nullptr.
*
* @param ptr Pointer to assert not nullptr.
*/
void assertNotNullptr(const void *ptr);
/** /**
* Asserts a given pointer to be a nullptr. * Asserts a given pointer to be a nullptr.
* @param pointer Pointer to assert is nullptr. * @param pointer Pointer to assert is nullptr.
@ -66,9 +54,5 @@ static inline void assertDeprecated() {}
#else #else
#define assertTrue assert #define assertTrue assert
#define assertFalse(x) assertTrue(x == 0)
#define assertNotNull(x) assert(x != NULL)
#define assertUnreachable() assert(false)
#define assertDeprecated assertUnreachable
#endif #endif

View File

@ -1,18 +1,20 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "AssetManager.hpp" #include "AssetManager.hpp"
using namespace Dawn; using namespace Dawn;
Asset::Asset(AssetManager &assetManager, std::string name) : Asset::Asset(AssetManager *assetManager, std::string name) {
assetManager(assetManager) assertTrue(name.size() > 0);
{ assertNotNull(assetManager);
this->name = name;
} this->assetManager = assetManager;
this->name = name;
Asset::~Asset() { }
this->loaded = false;
Asset::~Asset() {
this->loaded = false;
} }

View File

@ -1,46 +1,47 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "assert/assert.hpp"
namespace Dawn {
class AssetManager; namespace Dawn {
class AssetManager;
class Asset {
public: class Asset {
AssetManager &assetManager; public:
std::string name; AssetManager *assetManager;
uint8_t state = 0x00; std::string name;
bool loaded = false; uint8_t state = 0x00;
bool loaded = false;
/**
* Create an abstract Asset object. /**
* * Create an abstract Asset object.
* @param assetManager Asset manager that this asset belongs to. *
* @param name Name of the asset. * @param assetManager Asset manager that this asset belongs to.
*/ * @param name Name of the asset.
Asset(AssetManager &assetManager, std::string name); */
Asset(AssetManager *assetManager, 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 * Virtual function that will be called by the asset manager on a
* the loaded is also false. * synchronous basis. This will only trigger if the blocks are false and
*/ * the loaded is also false.
virtual void updateSync() = 0; */
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 * Virtual function called by the asset manager asynchronously every tick.
* false. * This will only trigger if blocks are false and the loaded state is also
*/ * false.
virtual void updateAsync() = 0; */
virtual void updateAsync() = 0;
/**
* Dispose the asset item. /**
*/ * Dispose the asset item.
virtual ~Asset(); */
}; virtual ~Asset();
};
} }

View File

@ -1,87 +1,99 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "AssetLoader.hpp" #include "AssetLoader.hpp"
using namespace Dawn; using namespace Dawn;
AssetLoader::AssetLoader(std::string fileName) { AssetLoader::AssetLoader(std::string fileName) {
this->fileName = fileName; assertTrue(fileName.size() > 0);
this->handle = nullptr;
} this->fileName = fileName;
this->handle = nullptr;
void AssetLoader::open() { }
std::string pathFull = DAWN_ASSET_BUILD_PREFIX + this->fileName;
this->handle = fopen(pathFull.c_str(), "rb"); void AssetLoader::open() {
if(this->handle == NULL || this->handle == nullptr) { assertNull(this->handle);
throw "Failed to open file handle for " + this->fileName; std::string pathFull = DAWN_ASSET_BUILD_PREFIX + this->fileName;
} this->handle = fopen(pathFull.c_str(), "rb");
} assertNotNull(this->handle);
}
int32_t AssetLoader::close() {
int32_t ret = fclose(this->handle); int32_t AssetLoader::close() {
this->handle = nullptr; assertNotNull(this->handle);
return ret; int32_t ret = fclose(this->handle);
} this->handle = nullptr;
return ret;
size_t AssetLoader::read(uint8_t *buffer, size_t size) { }
return fread(buffer, 1, size, this->handle);
} size_t AssetLoader::read(uint8_t *buffer, size_t size) {
assertNotNull(buffer);
int32_t AssetLoader::end() { assertTrue(size > 0);
return fseek(this->handle, 0, SEEK_END); assertNotNull(this->handle);
} return fread(buffer, 1, size, this->handle);
}
size_t AssetLoader::skip(size_t n) {
return fseek(this->handle, n, SEEK_CUR); int32_t AssetLoader::end() {
} assertNotNull(this->handle);
return fseek(this->handle, 0, SEEK_END);
int32_t AssetLoader::rewind() { }
return fseek(this->handle, 0, SEEK_SET);
} size_t AssetLoader::skip(size_t n) {
assertTrue(n > 0);
size_t AssetLoader::getPosition() { assertNotNull(this->handle);
return ftell(this->handle); return fseek(this->handle, n, SEEK_CUR);
} }
size_t AssetLoader::loadRaw(uint8_t **buffer) { int32_t AssetLoader::rewind() {
size_t length, read; assertNotNull(this->handle);
return fseek(this->handle, 0, SEEK_SET);
// Open a buffer. }
this->open();
size_t AssetLoader::getPosition() {
// Read the count of bytes in the file assertNotNull(this->handle);
this->end(); return ftell(this->handle);
length = this->getPosition(); }
// Are we only reading the size? size_t AssetLoader::loadRaw(uint8_t **buffer) {
if(buffer == nullptr) { size_t length, read;
this->close();
return length; assertNotNull(buffer);
}
// Open a buffer.
// Reset to start this->open();
this->rewind();
// Read the count of bytes in the file
// Read the string then close the file handle. this->end();
*buffer = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * length)); length = this->getPosition();
read = this->read(*buffer, length);
this->close(); // Are we only reading the size?
if(buffer == nullptr) {
// Did we read successfully? this->close();
if(read < length) { return length;
throw "Failed to read all bytes of " + this->fileName; }
}
// Reset to start
// Read successfully, return the read bytes. this->rewind();
return read;
} // Read the string then close the file handle.
*buffer = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * length));
AssetLoader::~AssetLoader() { read = this->read(*buffer, length);
if(this->handle != nullptr) { this->close();
this->close();
this->handle = nullptr; // Did we read successfully?
} if(read < length) {
throw "Failed to read all bytes of " + this->fileName;
}
// Read successfully, return the read bytes.
return read;
}
AssetLoader::~AssetLoader() {
if(this->handle != nullptr) {
this->close();
this->handle = nullptr;
}
} }

View File

@ -1,126 +1,130 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "util/memory.hpp" #include "assert/assert.hpp"
#include "util/memory.hpp"
namespace Dawn {
class AssetLoader { namespace Dawn {
private: class AssetLoader {
std::string fileName; private:
FILE *handle; std::string fileName;
FILE *handle;
public:
/** public:
* Create a new asset loader. Asset Loaders can be used to load data from /**
* a file in a myriad of ways. * 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. *
*/ * @param fileName File name of the asset that is to be loaded.
AssetLoader(std::string fileName); */
AssetLoader(std::string fileName);
/**
* Platform-centric method to open a file buffer to an asset. /**
* * Platform-centric method to open a file buffer to an asset.
* @return 0 if success, otherwise for failure. *
*/ * @return 0 if success, otherwise for failure.
void open(); */
void open();
/**
* Closes the previously ppened asset. /**
* @return 0 if successful, otherwise false. * Closes the previously ppened asset.
*/ * @return 0 if successful, otherwise false.
int32_t close(); */
int32_t close();
/**
* Read bytes from buffer. /**
* @param buffer Pointer to a ubyte array to buffer data into. * Read bytes from buffer.
* @param size Length of the data buffer (How many bytes to read). * @param buffer Pointer to a ubyte array to buffer data into.
* @return The count of bytes read. * @param size Length of the data buffer (How many bytes to read).
*/ * @return The count of bytes read.
size_t read(uint8_t *buffer, size_t size); */
size_t read(uint8_t *buffer, size_t size);
/**
* Skip to the end of the buffer, useful to find the length of the buffer. /**
* @return 0 if successful, otherwise false. * Skip to the end of the buffer, useful to find the length of the buffer.
*/ * @return 0 if successful, otherwise false.
int32_t end(); */
int32_t end();
/**
* Method to skip n bytes in the buffer /**
* @param n Count of bytes to skip. * Method to skip n bytes in the buffer
* @return 0 if successful, otherwise unsuccessful. * @param n Count of bytes to skip.
*/ * @return 0 if successful, otherwise unsuccessful.
size_t skip(size_t n); */
size_t skip(size_t n);
/**
* Rewinds to the start of the asset buffer. /**
* @return 0 if successful, otherwise unsuccessful. * Rewinds to the start of the asset buffer.
*/ * @return 0 if successful, otherwise unsuccessful.
int32_t rewind(); */
int32_t rewind();
/**
* Retreive the current byte position within the asset that the head is /**
* at. * Retreive the current byte position within the asset that the head is
* @return Position (in bytes) that the current seek is at. * at.
*/ * @return Position (in bytes) that the current seek is at.
size_t getPosition(); */
size_t getPosition();
/**
* Loads the entire file into a raw buffer. /**
* @param buffer Pointer to where a pointer to the buffer will be stored. * Loads the entire file into a raw buffer.
* @return Size of the buffer that was read (in bytes). * @param buffer Pointer to where a pointer to the buffer will be stored.
*/ * @return Size of the buffer that was read (in bytes).
size_t loadRaw(uint8_t **buffer); */
size_t loadRaw(uint8_t **buffer);
/**
* Run a callback for each byte within the asset. The callback will /**
* receive each byte individually. * Run a callback for each byte within the asset. The callback will
* * receive each byte individually.
* @tparam T Type of instance to run callback against. *
* @param instance Instance of the object to run the callback against. * @tparam T Type of instance to run callback against.
* @param callback Callback method on the class to run the callback for. * @param instance Instance of the object to run the callback against.
* @return The count of bytes read. * @param callback Callback method on the class to run the callback for.
*/ * @return The count of bytes read.
template<class T> */
size_t loadBufferedCallback(T *instance, bool (T::*callback)(uint8_t n)) { template<class T>
uint8_t buffer[1024]; size_t loadBufferedCallback(T *instance, bool (T::*callback)(uint8_t n)) {
size_t read, length; uint8_t buffer[1024];
int32_t i; size_t read, length;
bool result; int32_t i;
bool result;
// Open the buffer.
this->open(); assertNotNull(instance);
assertNotNull(callback);
// Reset length size
length = 0; // Open the buffer.
this->open();
// Buffer from input
while((read = this->read(buffer, 1024)) != 0) { // Reset length size
for(i = 0; i < read; i++) { length = 0;
result = ((*instance).*(callback))(buffer[i]);
if(!result) { // Buffer from input
length += i; while((read = this->read(buffer, 1024)) != 0) {
break; for(i = 0; i < read; i++) {
} result = ((*instance).*(callback))(buffer[i]);
} if(!result) {
if(!result) break; length += i;
length += read; break;
} }
}
// Close the buffer if(!result) break;
this->close(); length += read;
}
return length;
} // Close the buffer
this->close();
/**
* Cleanup the asset loader. return length;
*/ }
virtual ~AssetLoader();
}; /**
* Cleanup the asset loader.
*/
virtual ~AssetLoader();
};
} }

View File

@ -1,37 +1,52 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "AssetManager.hpp" #include "AssetManager.hpp"
#if !defined(DAWN_ASSET_BUILD_PREFIX) #if !defined(DAWN_ASSET_BUILD_PREFIX)
#error Asset Prefix has not been defined. #error Asset Prefix has not been defined.
#endif #endif
using namespace Dawn; using namespace Dawn;
void AssetManager::init() { void AssetManager::init() {
} }
void AssetManager::update() { void AssetManager::update() {
auto it = this->assetsNotLoaded.begin(); auto it = this->assetsNotLoaded.begin();
while(it != this->assetsNotLoaded.end()) { while(it != this->assetsNotLoaded.end()) {
auto asset = it->second; auto asset = it->second;
if(asset->loaded) { if(asset->loaded) {
it = this->assetsNotLoaded.erase(it); it = this->assetsNotLoaded.erase(it);
continue; continue;
} }
asset->updateSync(); asset->updateSync();
asset->updateAsync(); asset->updateAsync();
if(asset->loaded) { if(asset->loaded) {
it = this->assetsNotLoaded.erase(it); it = this->assetsNotLoaded.erase(it);
continue; this->assets[asset->name] = asset;
} continue;
}
++it;
} ++it;
}
}
AssetManager::~AssetManager() {
auto it = this->assets.begin();
while(it != this->assets.end()) {
delete it->second;
++it;
}
auto it2 = this->assetsNotLoaded.begin();
while(it2 != this->assetsNotLoaded.end()) {
delete it2->second;
++it2;
}
} }

View File

@ -1,38 +1,42 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "asset/Asset.hpp" #include "Asset.hpp"
namespace Dawn { namespace Dawn {
class AssetManager { class AssetManager {
private: private:
/** List of pointers to assets, mapped by their asset key. */ /** List of pointers to assets, mapped by their asset key. */
std::map<std::string, std::shared_ptr<Asset>> assets; std::map<std::string, Asset*> assets;
std::map<std::string, std::shared_ptr<Asset>> assetsNotLoaded; std::map<std::string, Asset*> assetsNotLoaded;
public: public:
void init(); void init();
void update(); void update();
/** /**
* Creates and queue an asset to load. * Creates and queue an asset to load.
* *
* @param name Name of the asset to load. * @param name Name of the asset to load.
* @return The asset element to be loaded. * @return The asset element to be loaded.
*/ */
template<class T> template<class T>
std::shared_ptr<T> load(std::string name) { T * load(std::string name) {
auto existing = this->assets.find(name); assertTrue(name.size() > 0);
if(existing != this->assets.end()) {
return std::dynamic_pointer_cast<T>(existing->second); auto existing = this->assets.find(name);
} if(existing != this->assets.end()) {
auto asset = std::make_shared<T>(*this, name); return (T*)existing->second;
this->assets[name] = asset; }
this->assetsNotLoaded[name] = asset; auto asset = new T(this, name);
return asset; this->assets[name] = asset;
} this->assetsNotLoaded[name] = asset;
}; return asset;
}
~AssetManager();
};
} }

View File

@ -1,64 +1,64 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "TextureAsset.hpp" #include "TextureAsset.hpp"
using namespace Dawn; using namespace Dawn;
TextureAsset::TextureAsset(AssetManager &assetManager, std::string name) : TextureAsset::TextureAsset(AssetManager *assetManager, std::string name) :
Asset(assetManager, name), Asset(assetManager, name),
loader(name + ".texture") loader(name + ".texture"),
{ texture()
this->texture = std::make_shared<Texture>(); {
} }
void TextureAsset::updateSync() { void TextureAsset::updateSync() {
if( if(
this->state != 0x03 this->state != 0x03
) return; ) return;
this->state = 0x04; this->state = 0x04;
this->texture->setSize(this->width, this->height); this->texture.setSize(this->width, this->height);
this->texture->buffer(this->colors); this->texture.buffer(this->colors);
this->state = 0x05; this->state = 0x05;
this->loaded = true; this->loaded = true;
} }
void TextureAsset::updateAsync() { void TextureAsset::updateAsync() {
if(this->state != 0x00) return; if(this->state != 0x00) return;
this->state = 0x01; this->state = 0x01;
this->loader.loadRaw(&this->buffer); this->loader.loadRaw(&this->buffer);
this->state = 0x02; this->state = 0x02;
// Parse header data. // Parse header data.
char integer[32]; char integer[32];
size_t j = 0, i = 0; size_t j = 0, i = 0;
while(true) { while(true) {
auto c = this->buffer[i++]; auto c = this->buffer[i++];
if(c == '|') { if(c == '|') {
integer[j] = '\0'; integer[j] = '\0';
if(this->width == -1) { if(this->width == -1) {
this->width = atoi(integer); this->width = atoi(integer);
if(this->width <= 0) throw "Invalid width"; assertTrue(this->width > 0);
j = 0; j = 0;
continue; continue;
} else { } else {
this->height = atoi(integer); this->height = atoi(integer);
if(this->height <= 0) throw "Invalid height"; assertTrue(this->height > 0);
break; break;
} }
} }
integer[j++] = c; integer[j++] = c;
} }
this->colors = (struct Color *)((void *)(this->buffer + i)); this->colors = (struct Color *)((void *)(this->buffer + i));
this->state = 0x03; this->state = 0x03;
} }
TextureAsset::~TextureAsset() { TextureAsset::~TextureAsset() {
if(this->buffer != nullptr) { if(this->buffer != nullptr) {
memoryFree(this->buffer); memoryFree(this->buffer);
} }
} }

View File

@ -1,29 +1,40 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "../Asset.hpp" #include "../Asset.hpp"
#include "../AssetLoader.hpp" #include "../AssetLoader.hpp"
#include "display/Texture.hpp" #include "display/Texture.hpp"
namespace Dawn { namespace Dawn {
class TextureAsset : public Asset { class TextureAsset : public Asset {
protected: protected:
AssetLoader loader; AssetLoader loader;
uint8_t *buffer = nullptr; uint8_t *buffer = nullptr;
int32_t width = -1, height = -1; int32_t width = -1, height = -1;
struct Color *colors; struct Color *colors;
public: public:
std::shared_ptr<Texture> texture; Texture texture;
TextureAsset(AssetManager &assetManager, std::string name); /**
* Constructs a texture asset loader. You should instead use the parent
void updateSync() override; * asset managers' abstracted load method
void updateAsync() override; *
* @param assetManager Asset manager this asset belongs to.
~TextureAsset(); * @param name File name asset to load, omitting the extension.
}; */
TextureAsset(AssetManager *assetManager, std::string name);
void updateSync() override;
void updateAsync() override;
/**
* Dispose / Cleanup the texture asset. Will also dispose the underlying
* texture itself.
*/
~TextureAsset();
};
} }

View File

@ -1,76 +1,86 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "TrueTypeAsset.hpp" #include "TrueTypeAsset.hpp"
using namespace Dawn; using namespace Dawn;
TrueTypeAsset::TrueTypeAsset(AssetManager &assMan, std::string name) : TrueTypeAsset::TrueTypeAsset(AssetManager *assMan, std::string name) :
Asset(assMan, name), Asset(assMan, name),
loader(name + ".truetype") loader(name + ".truetype")
{ {
} }
void TrueTypeAsset::updateSync() { void TrueTypeAsset::updateSync() {
if(this->state != 0x04) return; if(this->state != 0x04) return;
this->font.texture.setSize(this->width, this->height); this->font.texture.setSize(this->width, this->height);
this->font.texture.buffer(this->pixels); this->font.texture.buffer(this->pixels);
auto i = this->pixels; auto i = this->pixels;
memoryCopy( memoryCopy(
this->characterData, this->characterData,
this->font.characterData, this->font.characterData,
sizeof(truetypechar_t) * TRUETYPE_NUM_CHARS sizeof(truetypechar_t) * TRUETYPE_NUM_CHARS
); );
this->state = 0x05;
this->loaded = true; memoryFree(this->buffer);
} this->buffer = nullptr;
void TrueTypeAsset::updateAsync() { this->state = 0x05;
int32_t fontSize; this->loaded = true;
size_t i, j; }
char intBuffer[32];
char c; void TrueTypeAsset::updateAsync() {
int32_t fontSize;
if(this->state != 0x00) return; size_t i, j;
char intBuffer[32];
this->state = 0x01; char c;
this->loader.loadRaw(&this->buffer);
this->state = 0x02; if(this->state != 0x00) return;
// Parse header data. this->state = 0x01;
i = j = 0; this->loader.loadRaw(&this->buffer);
width = -1, height = -1, fontSize = -1; this->state = 0x02;
while(true) {
c = this->buffer[i++]; // Parse header data.
if(c == '|') { i = j = 0;
intBuffer[j] = '\0'; width = -1, height = -1, fontSize = -1;
if(width == -1) { while(true) {
this->width = atoi(intBuffer); c = this->buffer[i++];
j = 0; if(c == '|') {
continue; intBuffer[j] = '\0';
} else if(height == -1) { if(width == -1) {
this->height = atoi(intBuffer); this->width = atoi(intBuffer);
j = 0; assertTrue(this->width > 0);
continue; j = 0;
} else { continue;
fontSize = atoi(intBuffer); } else if(height == -1) {
break; this->height = atoi(intBuffer);
} assertTrue(this->height > 0);
} j = 0;
intBuffer[j++] = c; continue;
} } else {
fontSize = atoi(intBuffer);
this->state = 0x03; assertTrue(fontSize > 0);
this->font.fontSize = fontSize; break;
this->pixels = (struct Color*)(this->buffer + i); }
this->characterData = (truetypechar_t*)( }
(uint8_t*)this->pixels + (this->width * this->height * sizeof(struct Color)) intBuffer[j++] = c;
); }
this->state = 0x04;
} this->state = 0x03;
this->font.fontSize = fontSize;
TrueTypeAsset::~TrueTypeAsset() { this->pixels = (struct Color*)(this->buffer + i);
this->characterData = (truetypechar_t*)(
(uint8_t*)this->pixels + (this->width * this->height * sizeof(struct Color))
);
this->state = 0x04;
}
TrueTypeAsset::~TrueTypeAsset() {
if(this->buffer != nullptr) {
memoryFree(this->buffer);
this->buffer = nullptr;
}
} }

View File

@ -1,30 +1,40 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "../Asset.hpp" #include "../Asset.hpp"
#include "../AssetLoader.hpp" #include "../AssetLoader.hpp"
#include "display/font/TrueTypeFont.hpp" #include "display/font/TrueTypeFont.hpp"
namespace Dawn { namespace Dawn {
class TrueTypeAsset : public Asset { class TrueTypeAsset : public Asset {
protected: protected:
AssetLoader loader; AssetLoader loader;
uint8_t *buffer = nullptr; uint8_t *buffer = nullptr;
truetypechar_t *characterData = nullptr; truetypechar_t *characterData = nullptr;
struct Color *pixels = nullptr; struct Color *pixels = nullptr;
int32_t width, height; int32_t width, height;
public: public:
TrueTypeFont font; TrueTypeFont font;
TrueTypeAsset(AssetManager &assMan, std::string name); /**
* Constructs a new True Type Asset. As with all other assets you should
void updateSync() override; * instead use the AssetManaager.load method.
void updateAsync() override; *
* @param assMan Asset manager that this asset belongs to.
~TrueTypeAsset(); * @param name Filename of this asset.
}; */
TrueTypeAsset(AssetManager *assMan, std::string name);
void updateSync() override;
void updateAsync() override;
/**
* Disposes / Cleans up the truetype asset.
*/
~TrueTypeAsset();
};
} }

View File

@ -1,140 +1,141 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "RenderPipeline.hpp" #include "RenderPipeline.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
#include "display/mesh/QuadMesh.hpp" #include "display/mesh/QuadMesh.hpp"
#include "scene/SceneItem.hpp"
using namespace Dawn;
using namespace Dawn;
RenderPipeline::RenderPipeline(RenderManager &renderManager) :
renderManager(renderManager) RenderPipeline::RenderPipeline(RenderManager *renderManager) {
{ assertNotNull(renderManager);
} this->renderManager = renderManager;
}
void RenderPipeline::init() {
void RenderPipeline::init() {
}
}
void RenderPipeline::render() {
this->renderScene(*this->renderManager.game.scene); void RenderPipeline::render() {
} this->renderScene(this->renderManager->game->scene);
}
void RenderPipeline::renderScene(Scene &scene) {
RenderTarget &backBuffer = this->renderManager.getBackBuffer(); void RenderPipeline::renderScene(Scene *scene) {
auto cameras = scene.findComponents<Camera>(); auto backBuffer = this->renderManager->getBackBuffer();
std::shared_ptr<Camera> backBufferCamera = nullptr; auto cameras = scene->findComponents<Camera>();
Camera *backBufferCamera = nullptr;
// First, render all non-backbuffer cameras.
auto it = cameras.begin(); // First, render all non-backbuffer cameras.
while(it != cameras.end()) { auto it = cameras.begin();
RenderTarget &cameraTarget = (*it)->getRenderTarget(); while(it != cameras.end()) {
RenderTarget *cameraTarget = (*it)->getRenderTarget();
// Leave the backbuffer camera(s) to last, so we skip them.
if(&cameraTarget == &backBuffer) { // Leave the backbuffer camera(s) to last, so we skip them.
backBufferCamera = *it; if(cameraTarget == backBuffer) {
} else { backBufferCamera = *it;
this->renderSceneCamera(scene, **it); } else {
} this->renderSceneCamera(scene, *it);
}
++it;
} ++it;
}
// Now render the backbuffer camera.
if(backBufferCamera == nullptr) return; // Now render the backbuffer camera.
this->renderSceneCamera(scene, *backBufferCamera); if(backBufferCamera == nullptr) return;
this->renderSceneCamera(scene, backBufferCamera);
// Now we try and render UI components
auto uiCanvasList = scene.findComponents<UICanvas>(); // Now we try and render UI components
auto itCanvas = uiCanvasList.begin(); auto uiCanvasList = scene->findComponents<UICanvas>();
while(itCanvas != uiCanvasList.end()) { auto itCanvas = uiCanvasList.begin();
this->renderUI(scene, *backBufferCamera, **itCanvas); while(itCanvas != uiCanvasList.end()) {
++itCanvas; this->renderUI(scene, backBufferCamera, *itCanvas);
} ++itCanvas;
} }
}
void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) {
RenderTarget &renderTarget = camera.getRenderTarget(); void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
renderTarget.bind(); RenderTarget *renderTarget = camera->getRenderTarget();
renderTarget.clear( renderTarget->bind();
RENDER_TARGET_CLEAR_FLAG_DEPTH | renderTarget->clear(
RENDER_TARGET_CLEAR_FLAG_COLOR RENDER_TARGET_CLEAR_FLAG_DEPTH |
); RENDER_TARGET_CLEAR_FLAG_COLOR
this->renderManager.setRenderFlags( );
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST | this->renderManager->setRenderFlags(
RENDER_MANAGER_RENDER_FLAG_BLEND RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
); RENDER_MANAGER_RENDER_FLAG_BLEND
);
auto meshes = scene.findComponents<MeshRenderer>();
auto it = meshes.begin(); auto meshes = scene->findComponents<MeshRenderer>();
while(it != meshes.end()) { auto it = meshes.begin();
auto mesh = *it; while(it != meshes.end()) {
auto material = mesh->item.getComponent<Material>(); auto mesh = *it;
auto material = mesh->item->getComponent<Material>();
// TODO: fallback material?
if(material == nullptr) { // TODO: fallback material?
++it; if(material == nullptr) {
continue; ++it;
} continue;
}
auto shader = material->getShader();
shader->bind(); auto shader = material->getShader();
shader->setGlobalParameters(camera.projection, camera.transform.getWorldTransform()); shader->bind();
shader->setMeshParameters(mesh->item.transform.getWorldTransform()); shader->setGlobalParameters(camera->projection, camera->transform->getWorldTransform());
material->setShaderParameters(); shader->setMeshParameters(mesh->item->transform.getWorldTransform());
material->setShaderParameters();
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
++it; mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
} ++it;
} }
}
void RenderPipeline::renderUI(
Scene &scene, void RenderPipeline::renderUI(
Camera &camera, Scene *scene,
UICanvas &canvas Camera *camera,
) { UICanvas *canvas
// Get the ) {
RenderTarget *renderTarget; // Get the
RenderTarget *renderTarget;
glm::mat4 transform;
glm::mat4 projection; glm::mat4 transform;
switch(canvas.drawType) { glm::mat4 projection;
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE: switch(canvas->drawType) {
transform = glm::mat4(1.0f); case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
projection = glm::ortho(0.0f, canvas.getWidth(), canvas.getHeight(), 0.0f); transform = glm::mat4(1.0f);
renderTarget = &camera.getRenderTarget(); projection = glm::ortho(0.0f, canvas->getWidth(), canvas->getHeight(), 0.0f);
break; renderTarget = camera->getRenderTarget();
default: break;
throw "UI Draw modes are not yet supported."; default:
} throw "UI Draw modes are not yet supported.";
}
// Clear / Bind / Update the render target.
renderTarget->bind(); // Clear / Bind / Update the render target.
renderTarget->clear( renderTarget->bind();
RENDER_TARGET_CLEAR_FLAG_DEPTH | renderTarget->clear(
RENDER_TARGET_CLEAR_FLAG_COLOR RENDER_TARGET_CLEAR_FLAG_DEPTH |
); RENDER_TARGET_CLEAR_FLAG_COLOR
this->renderManager.setRenderFlags( );
RENDER_MANAGER_RENDER_FLAG_BLEND | this->renderManager->setRenderFlags(
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST RENDER_MANAGER_RENDER_FLAG_BLEND |
); RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
);
// Prepare the UI Shader
auto shader = this->renderManager.getUIShader(); // Prepare the UI Shader
shader->bind(); auto shader = this->renderManager->getUIShader();
shader->setUICamera(transform, projection); shader->bind();
shader->setUICamera(transform, projection);
// Render the children
glm::mat4 rootMatrix = canvas.transform.getWorldTransform(); // Render the children
auto it = canvas.children.begin(); glm::mat4 rootMatrix = canvas->transform->getWorldTransform();
while(it != canvas.children.end()) { auto it = canvas->children.begin();
(*it)->draw(*shader, rootMatrix); while(it != canvas->children.end()) {
++it; (*it)->draw(shader, rootMatrix);
} ++it;
} }
}
RenderPipeline::~RenderPipeline() {
RenderPipeline::~RenderPipeline() {
} }

View File

@ -1,72 +1,72 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "display/RenderManager.hpp" #include "display/RenderManager.hpp"
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "scene/components/Components.hpp" #include "scene/components/Components.hpp"
#include "scene/components/ui/UICanvas.hpp" #include "scene/components/ui/UICanvas.hpp"
#include "ui/UIComponent.hpp" #include "ui/UIComponent.hpp"
namespace Dawn { namespace Dawn {
class RenderPipeline { class RenderPipeline {
public: public:
RenderManager &renderManager; RenderManager *renderManager;
/** /**
* Constructs a new RenderPipeline. Render Pipelines are my attempt to * Constructs a new RenderPipeline. Render Pipelines are my attempt to
* create both a flexible, but standard way to allow the individual games * create both a flexible, but standard way to allow the individual games
* to decide how they want to render the common scene-item models. * to decide how they want to render the common scene-item models.
* *
* @param renderManager Parent render manager this pipeline belongs to. * @param renderManager Parent render manager this pipeline belongs to.
*/ */
RenderPipeline(RenderManager &renderManager); RenderPipeline(RenderManager *renderManager);
/** /**
* Initialize the render pipeline. * Initialize the render pipeline.
*/ */
virtual void init(); virtual void init();
/** /**
* Renders the games' currently active scene, and all of its' cameras. * Renders the games' currently active scene, and all of its' cameras.
*/ */
virtual void render(); virtual void render();
/** /**
* Render a specific scene, usually just called for the currently active * Render a specific scene, usually just called for the currently active
* scene, but in future this could include sub-scenes. * scene, but in future this could include sub-scenes.
* *
* @param scene Scene to render. * @param scene Scene to render.
*/ */
virtual void renderScene(Scene &scene); virtual void renderScene(Scene *scene);
/** /**
* Render a specific camera on a specific scene. * Render a specific camera on a specific scene.
* *
* @param scene Scene to render. * @param scene Scene to render.
* @param camera Camera within the scene to render. * @param camera Camera within the scene to render.
*/ */
virtual void renderSceneCamera(Scene &scene, Camera &camera); virtual void renderSceneCamera(Scene *scene, Camera *camera);
/** /**
* Renders a UI Canvas to the back buffer. * Renders a UI Canvas to the back buffer.
* *
* @param scene Scene for the UI canvas. * @param scene Scene for the UI canvas.
* @param camera Main backbuffer camera for the canvas. * @param camera Main backbuffer camera for the canvas.
* @param canvas Canvas to render. * @param canvas Canvas to render.
*/ */
virtual void renderUI( virtual void renderUI(
Scene &scene, Scene *scene,
Camera &camera, Camera *camera,
UICanvas &canvas UICanvas *canvas
); );
/** /**
* Cleanup a render pipeline that has been initialized. * Cleanup a render pipeline that has been initialized.
*/ */
virtual ~RenderPipeline(); virtual ~RenderPipeline();
}; };
} }

View File

@ -1,58 +1,58 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "util/flag.hpp" #include "util/flag.hpp"
#include "display/Color.hpp" #include "display/Color.hpp"
#include "event/Event.hpp" #include "event/Event.hpp"
#define RENDER_TARGET_CLEAR_FLAG_COLOR FLAG_DEFINE(0) #define RENDER_TARGET_CLEAR_FLAG_COLOR FLAG_DEFINE(0)
#define RENDER_TARGET_CLEAR_FLAG_DEPTH FLAG_DEFINE(1) #define RENDER_TARGET_CLEAR_FLAG_DEPTH FLAG_DEFINE(1)
namespace Dawn { namespace Dawn {
class RenderTarget { class RenderTarget {
public: public:
Event<RenderTarget &, float_t, float_t> eventRenderTargetResized; Event<RenderTarget*, float_t, float_t> eventRenderTargetResized;
/** /**
* Return the width of the render target. * Return the width of the render target.
* *
* @return The width of the render target. * @return The width of the render target.
*/ */
virtual float_t getWidth() = 0; virtual float_t getWidth() = 0;
/** /**
* Return the height of the render target. * Return the height of the render target.
* *
* @return The height of the render target. * @return The height of the render target.
*/ */
virtual float_t getHeight() = 0; virtual float_t getHeight() = 0;
/** /**
* Sets the clear color of the render target when the clear method for * Sets the clear color of the render target when the clear method for
* the color buffer is requested. * the color buffer is requested.
* *
* @param color Color to use for the clear operation. * @param color Color to use for the clear operation.
*/ */
virtual void setClearColor(struct Color color) = 0; virtual void setClearColor(struct Color color) = 0;
/** /**
* Request the existing data in the render target to be cleared out. We * Request the existing data in the render target to be cleared out. We
* typically assume the render target can support multiple buffer types, * typically assume the render target can support multiple buffer types,
* so you can opt to only clear certain buffer types. * so you can opt to only clear certain buffer types.
* *
* @param clearFlags Flags to request what is going to be cleared. * @param clearFlags Flags to request what is going to be cleared.
*/ */
virtual void clear(flag8_t clearFlags) = 0; virtual void clear(flag8_t clearFlags) = 0;
/** /**
* Bind the render target for rendering to. The proceeding render requests * Bind the render target for rendering to. The proceeding render requests
* will want to render to this render target directly. In future I may * 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 * see if we can have multiple render targets bound at once to make this
* operation perform faster. * operation perform faster.
*/ */
virtual void bind() = 0; virtual void bind() = 0;
}; };
} }

View File

@ -1,160 +1,161 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "Transform.hpp" #include "Transform.hpp"
#include "scene/SceneItem.hpp" #include "scene/SceneItem.hpp"
using namespace Dawn; using namespace Dawn;
Transform::Transform(SceneItem &item) : Transform::Transform(SceneItem *item) :
item(item), transformLocal(1.0f),
transformLocal(1.0f), transformWorld(1.0f)
transformWorld(1.0f) {
{ assertNotNull(item);
this->updateLocalValuesFromLocalTransform(); this->item = item;
} this->updateLocalValuesFromLocalTransform();
}
void Transform::updateLocalValuesFromLocalTransform() {
glm::vec3 skew; void Transform::updateLocalValuesFromLocalTransform() {
glm::vec4 perspective; glm::vec3 skew;
glm::decompose( glm::vec4 perspective;
this->transformLocal, glm::decompose(
this->localScale, this->transformLocal,
this->localRotation, this->localScale,
this->localPosition, this->localRotation,
skew, perspective this->localPosition,
); skew, perspective
} );
}
void Transform::updateLocalTransformFromLocalValues() {
glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition); void Transform::updateLocalTransformFromLocalValues() {
glm::mat4 rotate = glm::mat4_cast(this->localRotation); glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition);
glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale); glm::mat4 rotate = glm::mat4_cast(this->localRotation);
this->transformLocal = translate * rotate * scale; glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale);
this->updateWorldTransformFromLocalTransform(); this->transformLocal = translate * rotate * scale;
} this->updateWorldTransformFromLocalTransform();
}
void Transform::updateWorldTransformFromLocalTransform() {
glm::mat4 newWorld(1.0f); void Transform::updateWorldTransformFromLocalTransform() {
auto parent = this->getParent(); glm::mat4 newWorld(1.0f);
if(parent != nullptr) newWorld = parent->getWorldTransform(); auto parent = this->getParent();
this->transformWorld = newWorld * transformLocal; if(parent != nullptr) newWorld = parent->getWorldTransform();
} this->transformWorld = newWorld * transformLocal;
}
void Transform::updateLocalTransformFromWorldTransform() {
glm::mat4 parentMat(1.0f); void Transform::updateLocalTransformFromWorldTransform() {
auto parent = this->getParent(); glm::mat4 parentMat(1.0f);
if(parent != nullptr) parentMat = parent->getWorldTransform(); auto parent = this->getParent();
this->transformLocal = parentMat / this->transformWorld; if(parent != nullptr) parentMat = parent->getWorldTransform();
this->updateLocalValuesFromLocalTransform(); this->transformLocal = parentMat / this->transformWorld;
} this->updateLocalValuesFromLocalTransform();
}
void Transform::updateChildrenTransforms() {
auto it = this->children.begin(); void Transform::updateChildrenTransforms() {
while(it != this->children.end()) { auto it = this->children.begin();
(*it)->updateWorldTransformFromLocalTransform(); while(it != this->children.end()) {
++it; (*it)->updateWorldTransformFromLocalTransform();
} ++it;
} }
}
void Transform::lookAt(glm::vec3 pos, glm::vec3 look) {
this->lookAt(pos, look, glm::vec3(0, 1, 0)); void Transform::lookAt(glm::vec3 pos, glm::vec3 look) {
} this->lookAt(pos, look, glm::vec3(0, 1, 0));
}
void Transform::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) {
this->setWorldTransform(glm::lookAt(pos, look, up)); void Transform::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) {
} this->setWorldTransform(glm::lookAt(pos, look, up));
}
glm::vec3 Transform::getLocalPosition() {
return this->localPosition; glm::vec3 Transform::getLocalPosition() {
} return this->localPosition;
}
void Transform::setLocalPosition(glm::vec3 position) {
this->localPosition = position; void Transform::setLocalPosition(glm::vec3 position) {
this->updateLocalTransformFromLocalValues(); this->localPosition = position;
this->updateChildrenTransforms(); this->updateLocalTransformFromLocalValues();
} this->updateChildrenTransforms();
}
glm::vec3 Transform::getLocalScale() {
return this->localScale; glm::vec3 Transform::getLocalScale() {
} return this->localScale;
}
void Transform::setLocalScale(glm::vec3 scale) {
this->localScale = scale; void Transform::setLocalScale(glm::vec3 scale) {
this->updateLocalTransformFromLocalValues(); this->localScale = scale;
this->updateChildrenTransforms(); this->updateLocalTransformFromLocalValues();
} this->updateChildrenTransforms();
}
glm::quat Transform::getLocalRotation() {
return this->localRotation; glm::quat Transform::getLocalRotation() {
} return this->localRotation;
}
void Transform::setLocalRotation(glm::quat rotation) {
this->localRotation = rotation; void Transform::setLocalRotation(glm::quat rotation) {
this->updateLocalTransformFromLocalValues(); this->localRotation = rotation;
this->updateChildrenTransforms(); this->updateLocalTransformFromLocalValues();
} this->updateChildrenTransforms();
}
glm::mat4 Transform::getLocalTransform() {
return this->transformLocal; glm::mat4 Transform::getLocalTransform() {
} return this->transformLocal;
}
void Transform::setLocalTransform(glm::mat4 transform) {
this->transformLocal = transform; void Transform::setLocalTransform(glm::mat4 transform) {
this->transformLocal = transform;
this->updateLocalValuesFromLocalTransform();
this->updateChildrenTransforms(); this->updateLocalValuesFromLocalTransform();
} this->updateChildrenTransforms();
}
glm::mat4 Transform::getWorldTransform() {
return this->transformWorld; glm::mat4 Transform::getWorldTransform() {
} return this->transformWorld;
}
void Transform::setWorldTransform(glm::mat4 transform) {
this->transformWorld = transform; void Transform::setWorldTransform(glm::mat4 transform) {
this->updateLocalTransformFromWorldTransform(); this->transformWorld = transform;
this->updateChildrenTransforms(); this->updateLocalTransformFromWorldTransform();
} this->updateChildrenTransforms();
}
void Transform::setParent(Transform *parent) {
if(parent == this) throw "Cannot self reference"; void Transform::setParent(Transform *parent) {
assertTrue(parent != this);
auto currentParent = this->getParent();
if(currentParent == parent) return; auto currentParent = this->getParent();
if(currentParent == parent) return;
if(currentParent != nullptr) {
auto it = currentParent->children.begin(); if(currentParent != nullptr) {
while(it != currentParent->children.end()) { auto it = currentParent->children.begin();
if(*it == this) { while(it != currentParent->children.end()) {
currentParent->children.erase(it); if(*it == this) {
break; currentParent->children.erase(it);
} break;
++it; }
} ++it;
} }
}
this->parent = parent;
if(parent != nullptr) parent->children.push_back(this); this->parent = parent;
if(parent != nullptr) parent->children.push_back(this);
this->updateLocalTransformFromWorldTransform();
this->updateChildrenTransforms(); this->updateLocalTransformFromWorldTransform();
} this->updateChildrenTransforms();
}
Transform * Transform::getParent() {
return this->parent; Transform * Transform::getParent() {
} return this->parent;
}
Transform::~Transform() {
this->setParent(nullptr); Transform::~Transform() {
this->setParent(nullptr);
auto it = this->children.begin();
while(it != this->children.end()) { auto it = this->children.begin();
(*it)->setParent(nullptr); while(it != this->children.end()) {
++it; (*it)->setParent(nullptr);
} ++it;
}
} }

View File

@ -1,145 +1,146 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "util/flag.hpp" #include "assert/assert.hpp"
#include "util/flag.hpp"
namespace Dawn {
class SceneItem; namespace Dawn {
class SceneItem;
class Transform : public std::enable_shared_from_this<Transform> {
private: class Transform {
// Local (real) values private:
glm::vec3 localPosition; // Local (real) values
glm::vec3 localScale; glm::vec3 localPosition;
glm::quat localRotation; glm::vec3 localScale;
glm::quat localRotation;
// Cached (non-real) values
glm::mat4 transformLocal; // Cached (non-real) values
glm::mat4 transformWorld; glm::mat4 transformLocal;
glm::mat4 transformWorld;
// glm::vec3 position;
// glm::vec3 scale; // glm::vec3 position;
// glm::quat rotation; // glm::vec3 scale;
// glm::quat rotation;
// Heirarchy
Transform *parent = nullptr; // Heirarchy
std::vector<Transform *> children; Transform *parent = nullptr;
std::vector<Transform *> children;
// Hidden methods
void updateLocalValuesFromLocalTransform(); // Hidden methods
void updateLocalTransformFromLocalValues(); void updateLocalValuesFromLocalTransform();
void updateWorldTransformFromLocalTransform(); void updateLocalTransformFromLocalValues();
void updateLocalTransformFromWorldTransform(); void updateWorldTransformFromLocalTransform();
void updateChildrenTransforms(); void updateLocalTransformFromWorldTransform();
void updateChildrenTransforms();
public:
SceneItem &item; public:
SceneItem *item;
/**
* Constructs a new transform instance. Currently I have bound transforms /**
* to their parent SceneItem, but in future I may allow them to become * Constructs a new transform instance. Currently I have bound transforms
* disconnected from each other, for example I really could use a special * to their parent SceneItem, but in future I may allow them to become
* transform designed purely for UI elements, since they don't act like * disconnected from each other, for example I really could use a special
* normal scene items, but for now Transforms and SceneItems are 1:1 * transform designed purely for UI elements, since they don't act like
* * normal scene items, but for now Transforms and SceneItems are 1:1
* @param item Item that this transform belongs to. *
*/ * @param item Item that this transform belongs to.
Transform(SceneItem &item); */
Transform(SceneItem *item);
/**
* Orients this transform to look at a given point in world space. /**
* * Orients this transform to look at a given point in world space.
* @param position Position of the origin of this transform. *
* @param look Position in world space this transform looks at. * @param position Position of the origin of this transform.
*/ * @param look Position in world space this transform looks at.
void lookAt(glm::vec3 position, glm::vec3 look); */
void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up); void lookAt(glm::vec3 position, glm::vec3 look);
void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up);
/**
* Returns the local position (position relative to "my parent"). /**
* @return The 3D local position in parent-relative space. * Returns the local position (position relative to "my parent").
*/ * @return The 3D local position in parent-relative space.
glm::vec3 getLocalPosition(); */
glm::vec3 getLocalPosition();
/**
* Update / Set the local position of this transform relative to my parent /**
* @param position Position to set for the local transform. * Update / Set the local position of this transform relative to my parent
*/ * @param position Position to set for the local transform.
void setLocalPosition(glm::vec3 position); */
void setLocalPosition(glm::vec3 position);
/**
* Retusn the scale of this item, relative to my parent. /**
* @return 3D Scale vector of this item in parent-relative space. * Retusn the scale of this item, relative to my parent.
*/ * @return 3D Scale vector of this item in parent-relative space.
glm::vec3 getLocalScale(); */
glm::vec3 getLocalScale();
/**
* Set the local scale of this item. /**
* @param scale Scale of this item, relative to its parent. * Set the local scale of this item.
*/ * @param scale Scale of this item, relative to its parent.
void setLocalScale(glm::vec3 scale); */
void setLocalScale(glm::vec3 scale);
/**
* Returns the local rotation for this transform. /**
* @return The local rotation (parent-relative). * Returns the local rotation for this transform.
*/ * @return The local rotation (parent-relative).
glm::quat getLocalRotation(); */
glm::quat getLocalRotation();
/**
* Set the local (parent-relative) rotation for this transform. /**
* @param rotation Rotation in parent relative space. * Set the local (parent-relative) rotation for this transform.
*/ * @param rotation Rotation in parent relative space.
void setLocalRotation(glm::quat rotation); */
void setLocalRotation(glm::quat rotation);
/**
* Returns the transform matrix for this transform, in parent-relative /**
* space. * Returns the transform matrix for this transform, in parent-relative
* @return The transform origin in parent-relative space. * space.
*/ * @return The transform origin in parent-relative space.
glm::mat4 getLocalTransform(); */
glm::mat4 getLocalTransform();
/**
* Sets the local transform matrix for this transform. /**
* @param transform Local (parent-relative) transform to set. * Sets the local transform matrix for this transform.
*/ * @param transform Local (parent-relative) transform to set.
void setLocalTransform(glm::mat4 transform); */
void setLocalTransform(glm::mat4 transform);
/**
* Returns the transformation matrix for this transform, in world-space. /**
* @return The transform origin in world-space. * Returns the transformation matrix for this transform, in world-space.
*/ * @return The transform origin in world-space.
glm::mat4 getWorldTransform(); */
glm::mat4 getWorldTransform();
/**
* Updates the transform's world-space. /**
* @param transform Sets the transform position in world-space. * Updates the transform's world-space.
*/ * @param transform Sets the transform position in world-space.
void setWorldTransform(glm::mat4 transform); */
void setWorldTransform(glm::mat4 transform);
/**
* Updates the transform that this transform is a child of. Will also /**
* handle disconnecting any existing parent. * Updates the transform that this transform is a child of. Will also
* * handle disconnecting any existing parent.
* @param p Parent that this transform is now a child of. *
*/ * @param p Parent that this transform is now a child of.
void setParent(Transform *p); */
void setParent(Transform *p);
/**
* Returns the parent transform of this transform, or nullptr if there is /**
* no parent for this transform. * Returns the parent transform of this transform, or nullptr if there is
* @return Pointer to the parent transform, or nullptr. * no parent for this transform.
*/ * @return Pointer to the parent transform, or nullptr.
Transform * getParent(); */
Transform * getParent();
/**
* Dispose and clenaup this transform, also removes self from parent. /**
*/ * Dispose and clenaup this transform, also removes self from parent.
~Transform(); */
~Transform();
friend SceneItem;
}; friend SceneItem;
};
} }

View File

@ -1,86 +1,89 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "RenderTarget.hpp" #include "RenderTarget.hpp"
#include "display/shader/Shader.hpp" #include "display/shader/Shader.hpp"
#include "display/shader/UIShader.hpp" #include "display/shader/UIShader.hpp"
#include "util/flag.hpp" #include "util/flag.hpp"
#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0) #define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0)
#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1) #define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1)
typedef flag_t renderflag_t; typedef flag_t renderflag_t;
namespace Dawn { namespace Dawn {
class DawnGame; class DawnGame;
class RenderPipeline; class RenderPipeline;
class IRenderManager { class IRenderManager {
protected: protected:
renderflag_t renderFlags = 0; renderflag_t renderFlags = 0;
public: public:
DawnGame &game; DawnGame *game;
std::shared_ptr<RenderPipeline> renderPipeline; RenderPipeline *renderPipeline;
/** /**
* Default constructor for a render manager instance. * Default constructor for a render manager instance.
* *
* @param game Game that this render manager belongs to. * @param game Game that this render manager belongs to.
*/ */
IRenderManager(DawnGame &game) : game(game) {} IRenderManager(DawnGame *game) {
assertNotNull(game);
/** this->game = game;
* Returns the primary render target (the backbuffer) that draws directly }
* to the screen.
* /**
* @return Shared pointer to the backbuffer render target. * Returns the primary render target (the backbuffer) that draws directly
*/ * to the screen.
virtual RenderTarget & getBackBuffer() = 0; *
* @return Shared pointer to the backbuffer render target.
/** */
* Returns the current render pipeline intended to be used for rendering virtual RenderTarget * getBackBuffer() = 0;
* the currently active scene on the game instance.
* /**
* @return Reference to the currently active main scene render pipeline. * Returns the current render pipeline intended to be used for rendering
*/ * the currently active scene on the game instance.
virtual RenderPipeline & getRenderPipeline() = 0; *
* @return Reference to the currently active main scene render pipeline.
/** */
* Returns the default shader, the default shader will be applied to the virtual RenderPipeline * getRenderPipeline() = 0;
* materials first.
* /**
* @return Reference to the default shader. * Returns the default shader, the default shader will be applied to the
*/ * materials first.
virtual std::shared_ptr<Shader> getDefaultShader() = 0; *
* @return Reference to the default shader.
/** */
* Returns the UI Shader used by the game's UI engine. virtual Shader * getDefaultShader() = 0;
*
* @return Pointer to the UI Shader. /**
*/ * Returns the UI Shader used by the game's UI engine.
virtual std::shared_ptr<UIShader> getUIShader() = 0; *
* @return Pointer to the UI Shader.
/** */
* Sets the render flags for the render manager to use. virtual UIShader * getUIShader() = 0;
*
* @param renderFlags Render flags to use. /**
*/ * Sets the render flags for the render manager to use.
virtual void setRenderFlags(renderflag_t renderFlags) = 0; *
* @param renderFlags Render flags to use.
/** */
* Initialize / Start the Render Manager. virtual void setRenderFlags(renderflag_t renderFlags) = 0;
*
* @param game Game instance this render manager belongs to. /**
*/ * Initialize / Start the Render Manager.
virtual void init() = 0; *
* @param game Game instance this render manager belongs to.
/** */
* Perform a synchronous frame update on the render manager. virtual void init() = 0;
*/
virtual void update() = 0; /**
}; * Perform a synchronous frame update on the render manager.
*/
virtual void update() = 0;
};
} }

View File

@ -1,19 +1,58 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/Color.hpp" #include "display/Color.hpp"
namespace Dawn { namespace Dawn {
class ITexture { class ITexture {
public: public:
virtual int32_t getWidth() = 0; /**
virtual int32_t getHeight() = 0; * Returns the width of the texture.
virtual void setSize(int32_t width, int32_t height) = 0; *
virtual void fill(struct Color) = 0; * @return Width of the texture.
virtual bool_t isReady() = 0; */
virtual void buffer(struct Color pixels[]) = 0; 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).
*/
virtual void setSize(int32_t width, int32_t height) = 0;
/**
* Fill a texture with a single color. This is stupidly costly.
*
* @param color Color to fill.
*/
virtual void fill(struct Color) = 0;
/**
* Returns true only when the texture has been loaded, sized and put on
* the gpu for rendering.
*
* @return True if ready, otherwise false.
*/
virtual bool_t isReady() = 0;
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so
* avoid doing this too often.
*
* @param pixels Array of pixels you're trying to buffer.
* @return The amount of bytes buffered to the texture.
*/
virtual void buffer(struct Color pixels[]) = 0;
};
} }

View File

@ -1,34 +1,72 @@
/** /**
* Copyright (c) 2022 Dominic Masters * Copyright (c) 2022 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#pragma once #pragma once
#include "display/mesh/Mesh.hpp" #include "display/mesh/Mesh.hpp"
#include "util/mathutils.hpp" #include "util/mathutils.hpp"
#include "display/Texture.hpp" #include "display/Texture.hpp"
#include "display/mesh/QuadMesh.hpp" #include "display/mesh/QuadMesh.hpp"
#include "FontMeasure.hpp" #include "FontMeasure.hpp"
#define FONT_NEWLINE '\n' #define FONT_NEWLINE '\n'
#define FONT_SPACE ' ' #define FONT_SPACE ' '
namespace Dawn { namespace Dawn {
class Font { class Font {
public: public:
virtual void buffer( /**
std::string text, * Buffer the characters of a string onto a primitive and get the result of the
float_t fontSize, * buffer back as a resulting generic measurement information structure. Note
float_t maxWidth, * that measure is REQUIRED, and must be DISPOSED after it has been calculated.
Mesh &mesh, *
struct FontMeasure *info * @param text String to buffer.
) = 0; * @param fontSize Font size to use for the buffer operation.
* @param maxWidth Maximum width (in pixels) to use to textwrap. -1 for no wrap.
virtual Texture & getTexture() = 0; * @param mesh Mesh to buffer the string on to.
virtual void draw(Mesh &mesh, int32_t startCharacter, int32_t length) = 0; * @param info Pointer to where you want to store resulting measurements.
virtual float_t getLineHeight(float_t fontSize) = 0; */
virtual float_t getDefaultFontSize() = 0; virtual void buffer(
}; std::string text,
float_t fontSize,
float_t maxWidth,
Mesh *mesh,
struct FontMeasure *info
) = 0;
/**
* Returns the texture that is used for a given font.
*
* @return Pointer to the texture used by this font.
*/
virtual Texture * getTexture() = 0;
/**
* Draw a previously buffered font primitive.
*
* @param mesh Mesh to draw.
* @param start Start character to draw.
* @param length Count of characters to draw, set to -1 to draw all.
*/
virtual void draw(Mesh *mesh, int32_t startCharacter, int32_t length) = 0;
/**
* Returns the line height of a given font and font size combination.
*
* @param fontSize Font size to get the line height for.
* @return The line height of this font at this font size.
*/
virtual float_t getLineHeight(float_t fontSize) = 0;
/**
* Retreive the default font size of a given font. Useful if you want to use
* the original font's font size for pixel-perfect rendering.
*
* @return The font size fo that font item.
*/
virtual float_t getDefaultFontSize() = 0;
};
} }

View File

@ -1,43 +1,50 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "FontMeasure.hpp" #include "FontMeasure.hpp"
using namespace Dawn; using namespace Dawn;
float_t FontMeasure::getWidth() { float_t FontMeasure::getWidth() {
return this->width; return this->width;
} }
float_t FontMeasure::getHeight() { float_t FontMeasure::getHeight() {
return this->height; return this->height;
} }
int32_t FontMeasure::getQuadCount() { int32_t FontMeasure::getQuadCount() {
return this->realLength; return this->realLength;
} }
float_t FontMeasure::getHeightOfLineCount(int32_t lineCount) { float_t FontMeasure::getHeightOfLineCount(int32_t lineCount) {
return this->lineHeight * lineCount; assertTrue(lineCount > 0);
} return this->lineHeight * lineCount;
}
size_t FontMeasure::getLineCount() {
return this->lines.size(); size_t FontMeasure::getLineCount() {
} return this->lines.size();
}
int32_t FontMeasure::getQuadsOnLine(int32_t line) {
return this->lines[line].length; int32_t FontMeasure::getQuadsOnLine(int32_t line) {
} assertTrue(line >= 0);
assertTrue(line < this->lines.size());
int32_t FontMeasure::getQuadIndexOnLine(int32_t line) { return this->lines[line].length;
return this->lines[line].start; }
}
int32_t FontMeasure::getQuadIndexOnLine(int32_t line) {
void FontMeasure::addLine(int32_t start, int32_t len) { assertTrue(line >= 0);
struct FontLineMeasure info; assertTrue(line < this->lines.size());
info.start = start; return this->lines[line].start;
info.length = len; }
this->lines.push_back(info);
void FontMeasure::addLine(int32_t start, int32_t len) {
assertTrue(start >= 0);
assertTrue(len >= 0);
struct FontLineMeasure info;
info.start = start;
info.length = len;
this->lines.push_back(info);
} }

View File

@ -1,50 +1,51 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "assert/assert.hpp"
namespace Dawn {
struct FontLineMeasure { namespace Dawn {
/** What (real character) index the line starts at */ struct FontLineMeasure {
int32_t start; /** What (real character) index the line starts at */
/** How many (real) characters the line is in length */ int32_t start;
int32_t length; /** How many (real) characters the line is in length */
}; int32_t length;
};
struct FontMeasure {
public: struct FontMeasure {
/** How many raw chars are in the string */ public:
int32_t length; /** How many raw chars are in the string */
int32_t length;
/** How many real characters (non whitespace) are in the string */
int32_t realLength; /** How many real characters (non whitespace) are in the string */
int32_t realLength;
/** The real character info for each line */
std::vector<struct FontLineMeasure> lines; /** The real character info for each line */
std::vector<struct FontLineMeasure> lines;
/** Dimensions of the string */
float_t width, height; /** Dimensions of the string */
float_t width, height;
/** Height of a single line */
float_t lineHeight; /** Height of a single line */
float_t lineHeight;
/**
* Internal method that adds a line to the text buffer process. /**
* * Internal method that adds a line to the text buffer process.
* @param start Start character index for the next line. *
* @param len Length of the next line. * @param start Start character index for the next line.
*/ * @param len Length of the next line.
void addLine(int32_t start, int32_t length); */
void addLine(int32_t start, int32_t length);
float_t getWidth();
float_t getHeight(); float_t getWidth();
int32_t getQuadsOnLine(int32_t line); float_t getHeight();
int32_t getQuadIndexOnLine(int32_t line); int32_t getQuadsOnLine(int32_t line);
float_t getHeightOfLineCount(int32_t lineCount); int32_t getQuadIndexOnLine(int32_t line);
size_t getLineCount(); float_t getHeightOfLineCount(int32_t lineCount);
int32_t getQuadCount(); size_t getLineCount();
}; int32_t getQuadCount();
};
} }

View File

@ -13,6 +13,12 @@
using namespace Dawn; using namespace Dawn;
void TrueTypeFont::bakeQuad(truetypequad_t *quad,float_t *x,float_t *y,char c){ void TrueTypeFont::bakeQuad(truetypequad_t *quad,float_t *x,float_t *y,char c){
assertNotNull(quad);
assertNotNull(x);
assertNotNull(y);
assertTrue(c >= TRUETYPE_FIRST_CHAR);
assertTrue(c < (TRUETYPE_FIRST_CHAR+TRUETYPE_NUM_CHARS));
stbtt_GetBakedQuad( stbtt_GetBakedQuad(
this->characterData, this->characterData,
this->texture.getWidth(), this->texture.getHeight(), this->texture.getWidth(), this->texture.getHeight(),
@ -40,11 +46,15 @@ void TrueTypeFont::buffer(
std::string text, std::string text,
float_t fontSize, float_t fontSize,
float_t maxWidth, float_t maxWidth,
Mesh &mesh, Mesh *mesh,
struct FontMeasure *info struct FontMeasure *info
) { ) {
auto stringLength = text.length(); assertNotNull(mesh);
assertNotNull(info);
assertTrue(fontSize > 0);
assertTrue(maxWidth == -1 || maxWidth > 0);
auto stringLength = text.length();
if(stringLength == 0) { if(stringLength == 0) {
info->length = 0; info->length = 0;
info->realLength = 0; info->realLength = 0;
@ -53,15 +63,18 @@ void TrueTypeFont::buffer(
info->width = 0; info->width = 0;
info->height = 0.0f; info->height = 0.0f;
info->lineHeight = 0.0f; info->lineHeight = 0.0f;
mesh.createBuffers(0, 0); mesh->createBuffers(0, 0);
return; return;
} }
auto quads = new truetypequad_t[stringLength]; auto quads = new truetypequad_t[stringLength];
assertNotNull(quads);
// Get the font scale // Get the font scale
auto scale = this->getScale(fontSize); auto scale = this->getScale(fontSize);
assertTrue(scale > 0);
// Adjust the max width to match the scale, and allow "no max width". // Adjust the max width to match the scale, and allow "no max width".
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale); maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
@ -143,7 +156,7 @@ void TrueTypeFont::buffer(
} }
// Initialize primitive // Initialize primitive
mesh.createBuffers( mesh->createBuffers(
QUAD_VERTICE_COUNT * info->realLength, QUAD_VERTICE_COUNT * info->realLength,
QUAD_INDICE_COUNT * info->realLength QUAD_INDICE_COUNT * info->realLength
); );
@ -163,7 +176,7 @@ void TrueTypeFont::buffer(
info->height = mathMax<float_t>(info->height, quad->y1); info->height = mathMax<float_t>(info->height, quad->y1);
// Buffer the quad. // Buffer the quad.
QuadMesh::bufferQuadMesh(&mesh, QuadMesh::bufferQuadMesh(mesh,
glm::vec2(quad->x0, quad->y0), glm::vec2(quad->s0, quad->t0), glm::vec2(quad->x0, quad->y0), glm::vec2(quad->s0, quad->t0),
glm::vec2(quad->x1, quad->y1), glm::vec2(quad->s1, quad->t1), glm::vec2(quad->x1, quad->y1), glm::vec2(quad->s1, quad->t1),
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
@ -173,12 +186,14 @@ void TrueTypeFont::buffer(
delete quads; delete quads;
} }
Texture & TrueTypeFont::getTexture() { Texture * TrueTypeFont::getTexture() {
return this->texture; return &this->texture;
} }
void TrueTypeFont::draw(Mesh &mesh, int32_t startchar, int32_t length) { void TrueTypeFont::draw(Mesh *mesh, int32_t startchar, int32_t length) {
mesh.draw( assertNotNull(mesh);
mesh->draw(
MESH_DRAW_MODE_TRIANGLES, MESH_DRAW_MODE_TRIANGLES,
startchar * QUAD_INDICE_COUNT, startchar * QUAD_INDICE_COUNT,
length == -1 ? length : length * QUAD_INDICE_COUNT length == -1 ? length : length * QUAD_INDICE_COUNT
@ -186,10 +201,10 @@ void TrueTypeFont::draw(Mesh &mesh, int32_t startchar, int32_t length) {
} }
float_t TrueTypeFont::getLineHeight(float_t fontSize) { float_t TrueTypeFont::getLineHeight(float_t fontSize) {
assertTrue(fontSize > 0);
return 13.0f; return 13.0f;
} }
float_t TrueTypeFont::getDefaultFontSize() { float_t TrueTypeFont::getDefaultFontSize() {
return (float_t)this->fontSize; return (float_t)this->fontSize;
} }

View File

@ -71,12 +71,11 @@ namespace Dawn {
std::string text, std::string text,
float_t fontSize, float_t fontSize,
float_t maxWidth, float_t maxWidth,
Mesh &mesh, Mesh *mesh,
struct FontMeasure *info struct FontMeasure *info
) override; ) override;
Texture * getTexture() override;
Texture & getTexture() override; void draw(Mesh *mesh, int32_t startCharacter, int32_t length) override;
void draw(Mesh &mesh, int32_t startCharacter, int32_t length) override;
float_t getLineHeight(float_t fontSize) override; float_t getLineHeight(float_t fontSize) override;
float_t getDefaultFontSize() override; float_t getDefaultFontSize() override;
}; };

View File

@ -1,64 +1,66 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "CubeMesh.hpp" #include "CubeMesh.hpp"
using namespace Dawn; using namespace Dawn;
void CubeMesh::buffer( void CubeMesh::buffer(
Mesh &mesh, Mesh *mesh,
glm::vec3 pos, glm::vec3 size, glm::vec3 pos, glm::vec3 size,
int32_t verticeStart, int32_t indiceStart int32_t verticeStart, int32_t indiceStart
) { ) {
mesh.bufferPositions(verticeStart, std::array<glm::vec3, CUBE_VERTICE_COUNT>{{ assertNotNull(mesh);
pos,
glm::vec3(pos.x+size.x, pos.y, pos.z), mesh->bufferPositions(verticeStart, std::array<glm::vec3, CUBE_VERTICE_COUNT>{{
glm::vec3(pos.x, pos.y+size.y, pos.z), pos,
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z), glm::vec3(pos.x+size.x, pos.y, pos.z),
glm::vec3(pos.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+size.y, pos.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), glm::vec3(pos.x, pos.y, pos.z+size.z),
pos + size 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
mesh.bufferCoordinates(verticeStart,std::array<glm::vec2,CUBE_VERTICE_COUNT>{{ }});
glm::vec2(0, 0),
glm::vec2(1, 0), mesh->bufferCoordinates(verticeStart,std::array<glm::vec2,CUBE_VERTICE_COUNT>{{
glm::vec2(0, 1), glm::vec2(0, 0),
glm::vec2(1, 1), glm::vec2(1, 0),
glm::vec2(0, 1),
glm::vec2(0, 0), glm::vec2(1, 1),
glm::vec2(1, 0),
glm::vec2(0, 1), glm::vec2(0, 0),
glm::vec2(1, 1) glm::vec2(1, 0),
}}); glm::vec2(0, 1),
glm::vec2(1, 1)
mesh.bufferIndices(indiceStart, std::array<meshindice_t, CUBE_INDICE_COUNT>{{ }});
// Back
verticeStart, verticeStart + 1, verticeStart + 3, mesh->bufferIndices(indiceStart, std::array<meshindice_t, CUBE_INDICE_COUNT>{{
verticeStart, verticeStart + 2, verticeStart + 3, // Back
verticeStart, verticeStart + 1, verticeStart + 3,
// Right verticeStart, verticeStart + 2, verticeStart + 3,
verticeStart + 1, verticeStart + 5, verticeStart + 7,
verticeStart + 1, verticeStart + 3, verticeStart + 7, // Right
verticeStart + 1, verticeStart + 5, verticeStart + 7,
// Left verticeStart + 1, verticeStart + 3, verticeStart + 7,
verticeStart + 4, verticeStart, verticeStart + 2,
verticeStart + 4, verticeStart + 6, verticeStart + 2, // Left
verticeStart + 4, verticeStart, verticeStart + 2,
// Front verticeStart + 4, verticeStart + 6, verticeStart + 2,
verticeStart + 5, verticeStart + 4, verticeStart + 6,
verticeStart + 5, verticeStart + 7, verticeStart + 6, // Front
verticeStart + 5, verticeStart + 4, verticeStart + 6,
// Top verticeStart + 5, verticeStart + 7, verticeStart + 6,
verticeStart + 7, verticeStart + 2, verticeStart + 6,
verticeStart + 7, verticeStart + 3, verticeStart + 2, // Top
verticeStart + 7, verticeStart + 2, verticeStart + 6,
// Bottom verticeStart + 7, verticeStart + 3, verticeStart + 2,
verticeStart + 1, verticeStart, verticeStart + 4,
verticeStart + 1, verticeStart + 4, verticeStart + 5 // Bottom
}}); verticeStart + 1, verticeStart, verticeStart + 4,
verticeStart + 1, verticeStart + 4, verticeStart + 5
}});
} }

View File

@ -1,21 +1,21 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/mesh/Mesh.hpp" #include "display/mesh/Mesh.hpp"
#define CUBE_VERTICE_COUNT 8 #define CUBE_VERTICE_COUNT 8
#define CUBE_INDICE_COUNT 36 #define CUBE_INDICE_COUNT 36
namespace Dawn { namespace Dawn {
class CubeMesh { class CubeMesh {
public: public:
static void buffer( static void buffer(
Mesh &mesh, Mesh *mesh,
glm::vec3 pos, glm::vec3 size, glm::vec3 pos, glm::vec3 size,
int32_t verticeStart, int32_t indiceStart int32_t verticeStart, int32_t indiceStart
); );
}; };
} }

View File

@ -1,49 +1,51 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "QuadMesh.hpp" #include "QuadMesh.hpp"
using namespace Dawn; using namespace Dawn;
void QuadMesh::bufferQuadMeshWithZ( void QuadMesh::bufferQuadMeshWithZ(
Mesh *mesh, Mesh *mesh,
glm::vec2 xy0, glm::vec2 uv0, glm::vec2 xy0, glm::vec2 uv0,
glm::vec2 xy1, glm::vec2 uv1, glm::vec2 xy1, glm::vec2 uv1,
float_t z, int32_t verticeStart, int32_t indiceStart float_t z, int32_t verticeStart, int32_t indiceStart
) { ) {
mesh->bufferPositions( assertNotNull(mesh);
verticeStart, std::array<glm::vec3, QUAD_VERTICE_COUNT>{{
glm::vec3(xy0, z), mesh->bufferPositions(
glm::vec3(xy1.x, xy0.y, z), verticeStart, std::array<glm::vec3, QUAD_VERTICE_COUNT>{{
glm::vec3(xy0.x, xy1.y, z), glm::vec3(xy0, z),
glm::vec3(xy1, z) glm::vec3(xy1.x, xy0.y, z),
}} glm::vec3(xy0.x, xy1.y, z),
); glm::vec3(xy1, z)
}}
mesh->bufferCoordinates( );
verticeStart, std::array<glm::vec2, QUAD_VERTICE_COUNT>{{
uv0, glm::vec2(uv1.x, uv0.y), mesh->bufferCoordinates(
glm::vec2(uv0.x, uv1.y), uv1 verticeStart, std::array<glm::vec2, QUAD_VERTICE_COUNT>{{
}} uv0, glm::vec2(uv1.x, uv0.y),
); glm::vec2(uv0.x, uv1.y), uv1
}}
mesh->bufferIndices( );
indiceStart, std::array<meshindice_t, QUAD_INDICE_COUNT>{{
verticeStart, verticeStart + 1, verticeStart + 2, mesh->bufferIndices(
verticeStart + 1, verticeStart + 2, verticeStart + 3 indiceStart, std::array<meshindice_t, QUAD_INDICE_COUNT>{{
}} verticeStart, verticeStart + 1, verticeStart + 2,
); verticeStart + 1, verticeStart + 2, verticeStart + 3
} }}
);
void QuadMesh::bufferQuadMesh( }
Mesh *mesh,
glm::vec2 xy0, glm::vec2 uv0, void QuadMesh::bufferQuadMesh(
glm::vec2 xy1, glm::vec2 uv1, Mesh *mesh,
int32_t verticeStart, int32_t indiceStart glm::vec2 xy0, glm::vec2 uv0,
) { glm::vec2 xy1, glm::vec2 uv1,
QuadMesh::bufferQuadMeshWithZ( int32_t verticeStart, int32_t indiceStart
mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart ) {
); QuadMesh::bufferQuadMeshWithZ(
mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart
);
} }

View File

@ -1,25 +1,27 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "display/mesh/TriangleMesh.hpp" #include "display/mesh/TriangleMesh.hpp"
using namespace Dawn; using namespace Dawn;
void TriangleMesh::createTriangleMesh(Mesh &mesh) { void TriangleMesh::createTriangleMesh(Mesh *mesh) {
mesh.createBuffers(3, 3); assertNotNull(mesh);
mesh.bufferPositions(0, std::array<glm::vec3, 3>{{
glm::vec3(-0.5f, -0.5f, 0), mesh->createBuffers(3, 3);
glm::vec3(0.5f, -0.5f, 0), mesh->bufferPositions(0, std::array<glm::vec3, 3>{{
glm::vec3(0, 0.5f, 0) glm::vec3(-0.5f, -0.5f, 0),
}}); glm::vec3(0.5f, -0.5f, 0),
mesh.bufferCoordinates(0, std::array<glm::vec2, 3>{{ glm::vec3(0, 0.5f, 0)
glm::vec2(0, 0), }});
glm::vec2(0, 1), mesh->bufferCoordinates(0, std::array<glm::vec2, 3>{{
glm::vec2(1, 0) glm::vec2(0, 0),
}}); glm::vec2(0, 1),
mesh.bufferIndices(0, std::array<meshindice_t,3>{{ glm::vec2(1, 0)
0, 1, 2 }});
}}); mesh->bufferIndices(0, std::array<meshindice_t,3>{{
0, 1, 2
}});
} }

View File

@ -1,19 +1,19 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/mesh/Mesh.hpp" #include "display/mesh/Mesh.hpp"
namespace Dawn { namespace Dawn {
class TriangleMesh { class TriangleMesh {
public: public:
/** /**
* Initializes a mesh to hold a single triangle. * Initializes a mesh to hold a single triangle.
* *
* @param mesh Mesh to initialize as a triangle. * @param mesh Mesh to initialize as a triangle.
*/ */
static void createTriangleMesh(Mesh &mesh); static void createTriangleMesh(Mesh *mesh);
}; };
} }

View File

@ -33,7 +33,7 @@ namespace Dawn {
* *
* @param material Material to set the default parameters on to. * @param material Material to set the default parameters on to.
*/ */
virtual void setDefaultParameters(Material &material) = 0; virtual void setDefaultParameters(Material *material) = 0;
/** /**
* Requested by the render pipeline (typically) to set global level (once * Requested by the render pipeline (typically) to set global level (once

View File

@ -1,119 +1,119 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "assert/assert.hpp"
namespace Dawn {
namespace Dawn {
template<typename... A>
struct IEventListener { template<typename... A>
/** struct IEventListener {
* Abstracted method for C++ template reasons. Invokes the listener. /**
* * Abstracted method for C++ template reasons. Invokes the listener.
* @param args Arguments to pass to the listener. *
*/ * @param args Arguments to pass to the listener.
virtual void invoke(A... args) = 0; */
}; virtual void invoke(A... args) = 0;
};
template <class T, typename... A>
struct EventListener : public IEventListener<A...> { template <class T, typename... A>
T *instance; struct EventListener : public IEventListener<A...> {
void (T::*callback)(A... args); T *instance;
void (T::*callback)(A... args);
/**
* Construct a new event listener structure. /**
* * Construct a new event listener structure.
* @param instance Instance that the callback belongs to. *
* @param callback Callback method that invokes back. * @param instance Instance that the callback belongs to.
*/ * @param callback Callback method that invokes back.
EventListener(T *instance, void (T::*callback)(A... args)) : */
instance(instance), EventListener(T *instance, void (T::*callback)(A... args)) {
callback(callback) this->instance = instance;
{ this->callback = callback;
} }
void invoke(A... args) { void invoke(A... args) {
((*this->instance).*(this->callback))(args...); ((*this->instance).*(this->callback))(args...);
} }
}; };
template<typename...A> template<typename...A>
class Event { class Event {
private: private:
std::vector<IEventListener<A...>*> listeners; std::vector<IEventListener<A...>*> listeners;
public: public:
/** /**
* Add a listener to this event. * Add a listener to this event.
* *
* @tparam T The class that will receive the event. * @tparam T The class that will receive the event.
* @param instance Instance of type T that will receive the callback. * @param instance Instance of type T that will receive the callback.
* @param callback Callback method attached to T to receive the event. * @param callback Callback method attached to T to receive the event.
* @return The initialized event listener. You don't really need this. * @return The initialized event listener. You don't really need this.
*/ */
template<class T> template<class T>
EventListener<T, A...> * addListener( EventListener<T, A...> * addListener(
T *instance, T *instance,
void (T::*callback)(A... args) void (T::*callback)(A... args)
) { ) {
auto listener = new EventListener<T,A...>(instance, callback); auto listener = new EventListener<T,A...>(instance, callback);
this->listeners.push_back(listener); this->listeners.push_back(listener);
return listener; return listener;
} }
/** /**
* Removes an event listener from this event. * Removes an event listener from this event.
* *
* @tparam T The class that was once receiving the event. * @tparam T The class that was once receiving the event.
* @param instance Instance of type T that did receive the callback. * @param instance Instance of type T that did receive the callback.
* @param callback Callback method attached to T for the event. * @param callback Callback method attached to T for the event.
*/ */
template<class T> template<class T>
void removeListener( void removeListener(
T *instance, T *instance,
void (T::*callback)(A... args) void (T::*callback)(A... args)
) { ) {
auto it = this->listeners.begin(); auto it = this->listeners.begin();
while(it != this->listeners.end()) { while(it != this->listeners.end()) {
auto listener = static_cast<EventListener<T,A...>*>(*it); auto listener = static_cast<EventListener<T,A...>*>(*it);
if(listener->instance != instance || listener->callback != callback) { if(listener->instance != instance || listener->callback != callback) {
++it; ++it;
continue; continue;
} }
this->listeners.erase(it); this->listeners.erase(it);
delete listener; delete listener;
break; break;
} }
} }
/** /**
* Invokes the event and emits to all of the listeners. * Invokes the event and emits to all of the listeners.
* *
* @param args Arguments for this event to pass to the listeners. * @param args Arguments for this event to pass to the listeners.
*/ */
void invoke(A... args) { void invoke(A... args) {
auto it = this->listeners.begin(); auto it = this->listeners.begin();
while(it != this->listeners.end()) { while(it != this->listeners.end()) {
(*it)->invoke(args...); (*it)->invoke(args...);
++it; ++it;
} }
} }
/** /**
* Disposes the event instance. Will also destroy all of the event * Disposes the event instance. Will also destroy all of the event
* listeners. * listeners.
*/ */
~Event() { ~Event() {
auto it = this->listeners.begin(); auto it = this->listeners.begin();
while(it != this->listeners.end()) { while(it != this->listeners.end()) {
delete *it; delete *it;
++it; ++it;
} }
} }
}; };
} }

View File

@ -21,7 +21,7 @@ namespace Dawn {
class IDawnGame { class IDawnGame {
public: public:
std::shared_ptr<Scene> scene; Scene *scene;
/** /**
* Initialize the game. This is performed by the host at a time that is * Initialize the game. This is performed by the host at a time that is

View File

@ -1,92 +1,90 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
/** Implies the host initialized successfully */ /** Implies the host initialized successfully */
#define DAWN_HOST_INIT_RESULT_SUCCESS 0 #define DAWN_HOST_INIT_RESULT_SUCCESS 0
/** Implies that the update was successful, and the loop should continue */ /** Implies that the update was successful, and the loop should continue */
#define DAWN_HOST_UPDATE_RESULT_SUCCESS 0 #define DAWN_HOST_UPDATE_RESULT_SUCCESS 0
/** Implies that the update was successful, but the loop should not continue */ /** Implies that the update was successful, but the loop should not continue */
#define DAWN_HOST_UPDATE_RESULT_EXIT 1 #define DAWN_HOST_UPDATE_RESULT_EXIT 1
/** Implies that the host started successfully */ /** Implies that the host started successfully */
#define DAWN_HOST_START_RESULT_SUCCESS 0 #define DAWN_HOST_START_RESULT_SUCCESS 0
/** Implies that the host started successfully, and then finished everything */ /** Implies that the host started successfully, and then finished everything */
#define DAWN_HOST_START_RESULT_EXIT_SUCCESS 1 #define DAWN_HOST_START_RESULT_EXIT_SUCCESS 1
namespace Dawn { namespace Dawn {
/** /**
* DawnHostData is a custom forwarder that allows any host to define what it * DawnHostData is a custom forwarder that allows any host to define what it
* will need access to, data-wise. For example, GLFW+GLAD uses this to hold * will need access to, data-wise. For example, GLFW+GLAD uses this to hold
* the window handle during the hosts' session, so that it can destroy it * the window handle during the hosts' session, so that it can destroy it
* safely when the host is unloaded. * safely when the host is unloaded.
*/ */
class DawnHostData; class DawnHostData;
class DawnHost : class DawnHost {
public std::enable_shared_from_this<DawnHost> public:
{ DawnHostData *data;
public: DawnGame *game;
std::unique_ptr<DawnHostData> data;
DawnGame *game; /**
* Construct a new DawnHost. Hosts are set by the various dawn platform
/** * libraries to be handled in different ways depending on the exact
* Construct a new DawnHost. Hosts are set by the various dawn platform * system. For example, Windows can support both GLFW+GLAD or SDL and may
* libraries to be handled in different ways depending on the exact * opt to invoke a DawnHost for either of these scenarios.
* system. For example, Windows can support both GLFW+GLAD or SDL and may */
* opt to invoke a DawnHost for either of these scenarios. DawnHost();
*/
DawnHost(); /**
* Request to initialize the host. Hosts can initialize themselves pretty
/** * much however they want, but they must return a status code, in cases
* Request to initialize the host. Hosts can initialize themselves pretty * where some hosts may not be responsible for their own invokation.
* much however they want, but they must return a status code, in cases *
* where some hosts may not be responsible for their own invokation. * @param game Game instance that this host is running for.
* * @return A status code, where DAWN_HOST_INIT_RESULT_SUCCESS is success.
* @param game Game instance that this host is running for. */
* @return A status code, where DAWN_HOST_INIT_RESULT_SUCCESS is success. int32_t init(DawnGame *game);
*/
int32_t init(DawnGame &game); /**
* Request to start the main loop. This method may not exist and may not
/** * need to exist depending on the host. For that reason this is marked as
* Request to start the main loop. This method may not exist and may not * virtual and is up to the main caller to know how this start method
* need to exist depending on the host. For that reason this is marked as * needs to be called. Start should request update() to be invoked if it
* virtual and is up to the main caller to know how this start method * does begin the main thread.
* needs to be called. Start should request update() to be invoked if it *
* does begin the main thread. * @param game Game instance that this host is running for.
* * @return A status code, refer to DAWN_HOST_START_RESULT_{} definitions.
* @param game Game instance that this host is running for. */
* @return A status code, refer to DAWN_HOST_START_RESULT_{} definitions. virtual int32_t start(DawnGame *game);
*/
virtual int32_t start(DawnGame &game); /**
* Requests the host to perform a main-thread update.
/** *
* Requests the host to perform a main-thread update. * @param game Game instance that this host is running for.
* * @param delta How much time has passed (in seconds) since the last tick.
* @param game Game instance that this host is running for. * @return A status code, refer to DAWN_HOST_UPDATE_RESULT_{} definitions.
* @param delta How much time has passed (in seconds) since the last tick. */
* @return A status code, refer to DAWN_HOST_UPDATE_RESULT_{} definitions. int32_t update(DawnGame *game, float_t delta);
*/
int32_t update(DawnGame &game, float_t delta); /**
* Request the host to be unloaded. This is a bit different from dispose
/** * as we are likely to unload the host just after the game is unloaded,
* Request the host to be unloaded. This is a bit different from dispose * but before the parent program has requested memory freeing.
* as we are likely to unload the host just after the game is unloaded, *
* but before the parent program has requested memory freeing. * @param game Game instance that this host is running for.
* */
* @param game Game instance that this host is running for. void unload(DawnGame *game);
*/
void unload(DawnGame &game); /**
* Destroy (and unload) all of the DawnHost data from memory.
/** */
* Destroy (and unload) all of the DawnHost data from memory. ~DawnHost();
*/ };
~DawnHost();
};
} }

View File

@ -1,161 +1,163 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "util/mathutils.hpp" #include "util/mathutils.hpp"
namespace Dawn { namespace Dawn {
class DawnGame; class DawnGame;
typedef int_fast16_t inputbind_t; typedef int_fast16_t inputbind_t;
template<typename T> template<typename T>
class IInputManager { class IInputManager {
protected: protected:
std::map<inputbind_t, std::vector<T>> binds; std::map<inputbind_t, std::vector<T>> binds;
std::map<inputbind_t, float_t> valuesLeft; std::map<inputbind_t, float_t> valuesLeft;
std::map<inputbind_t, float_t> valuesRight; std::map<inputbind_t, float_t> valuesRight;
bool_t currentIsLeft = true; bool_t currentIsLeft = true;
/** /**
* Method to be overwritten by the platform, reads a RAW input value from * Method to be overwritten by the platform, reads a RAW input value from
* the pad/input device directly. * the pad/input device directly.
* *
* @param axis Axis to get the value of. * @param axis Axis to get the value of.
* @return The current input value (between 0 and 1). * @return The current input value (between 0 and 1).
*/ */
virtual float_t getInputValue(T axis) = 0; virtual float_t getInputValue(T axis) = 0;
public: public:
DawnGame &game; DawnGame *game;
IInputManager(DawnGame &game) : game(game) {} IInputManager(DawnGame *game) {
this->game = game;
/** }
* Binds an axis to a bind.
* /**
* @param bind Bind to bind the axis to. * Binds an axis to a bind.
* @param axis Axis to use for this bind. *
*/ * @param bind Bind to bind the axis to.
void bind(inputbind_t bind, T axis) { * @param axis Axis to use for this bind.
this->binds[bind].push_back(axis); */
} void bind(inputbind_t bind, T axis) {
this->binds[bind].push_back(axis);
/** }
* Unbind a previously bound axis from a bind.
* /**
* @param bind Bind to remove all binds from. * Unbind a previously bound axis from a bind.
*/ *
void unbind(inputbind_t bind) { * @param bind Bind to remove all binds from.
this->binds[bind].clear(); */
} void unbind(inputbind_t bind) {
this->binds[bind].clear();
/** }
* Unbind all values, all of them.
*/ /**
void unbindAll() { * Unbind all values, all of them.
this->binds.clear(); */
this->values.clear(); void unbindAll() {
} this->binds.clear();
this->values.clear();
/** }
* Return the current bind value.
* /**
* @param bind Bind to get the value of. * Return the current bind value.
* @return The current input state (between 0 and 1). *
*/ * @param bind Bind to get the value of.
float_t getValue(inputbind_t bind) { * @return The current input state (between 0 and 1).
if(this->currentIsLeft) { */
auto exist = this->valuesLeft.find(bind); float_t getValue(inputbind_t bind) {
return exist == this->valuesLeft.end() ? 0.0f : exist->second; if(this->currentIsLeft) {
} else { auto exist = this->valuesLeft.find(bind);
auto exist = this->valuesRight.find(bind); return exist == this->valuesLeft.end() ? 0.0f : exist->second;
return exist == this->valuesRight.end() ? 0.0f : exist->second; } else {
} auto exist = this->valuesRight.find(bind);
} return exist == this->valuesRight.end() ? 0.0f : exist->second;
}
/** }
* Return the bind value from the previous frame.
* /**
* @param bind Bind to get the value of. * Return the bind value from the previous frame.
* @return The value of the bind, last frame. *
*/ * @param bind Bind to get the value of.
float_t getValueLastUpdate(inputbind_t bind) { * @return The value of the bind, last frame.
if(this->currentIsLeft) { */
auto exist = this->valuesRight.find(bind); float_t getValueLastUpdate(inputbind_t bind) {
return exist == this->valuesRight.end() ? 0.0f : exist->second; if(this->currentIsLeft) {
} else { auto exist = this->valuesRight.find(bind);
auto exist = this->valuesLeft.find(bind); return exist == this->valuesRight.end() ? 0.0f : exist->second;
return exist == this->valuesLeft.end() ? 0.0f : exist->second; } else {
} auto exist = this->valuesLeft.find(bind);
} return exist == this->valuesLeft.end() ? 0.0f : exist->second;
}
/** }
* Returns true if the given bind is currently being pressed (a non-zero
* value). /**
* * Returns true if the given bind is currently being pressed (a non-zero
* @param bind Bind to check if pressed. * value).
* @return True if value is non-zero, or false for zero. *
*/ * @param bind Bind to check if pressed.
bool_t isDown(inputbind_t bind) { * @return True if value is non-zero, or false for zero.
return this->getValue(bind) != 0.0f; */
} bool_t isDown(inputbind_t bind) {
return this->getValue(bind) != 0.0f;
/** }
* Returns true on the first frame an input was pressed (when the state
* had changed from 0 to non-zero). /**
* * Returns true on the first frame an input was pressed (when the state
* @param bind Bind to check if pressed. * had changed from 0 to non-zero).
* @return True if down this frame and not down last frame. *
*/ * @param bind Bind to check if pressed.
bool_t isPressed(inputbind_t bind) { * @return True if down this frame and not down last frame.
return this->getValue(bind)!=0 && this->getValueLastUpdate(bind)==0; */
} bool_t isPressed(inputbind_t bind) {
return this->getValue(bind)!=0 && this->getValueLastUpdate(bind)==0;
/** }
* Returns true on the first frame an input was released (when the state
* had changed from non-zero to 0). /**
* * Returns true on the first frame an input was released (when the state
* @param bind Bind to check if released. * had changed from non-zero to 0).
* @return True if up this frame, and down last frame. *
*/ * @param bind Bind to check if released.
bool_t wasReleased(inputbind_t bind) { * @return True if up this frame, and down last frame.
return this->getValue(bind)==0 && this->getValueLastUpdate(bind)!=0; */
} bool_t wasReleased(inputbind_t bind) {
return this->getValue(bind)==0 && this->getValueLastUpdate(bind)!=0;
/** }
* Internal method to update the input state, checks current input raws
* and decides what values are set for the inputs. /**
*/ * Internal method to update the input state, checks current input raws
void update() { * and decides what values are set for the inputs.
auto it = this->binds.begin(); */
this->currentIsLeft = !this->currentIsLeft; void update() {
auto it = this->binds.begin();
// For each bind... this->currentIsLeft = !this->currentIsLeft;
while(it != this->binds.end()) {
float_t value = 0.0f; // For each bind...
while(it != this->binds.end()) {
// For each input axis... float_t value = 0.0f;
auto bindIt = it->second.begin();
while(bindIt != it->second.end()) { // For each input axis...
// Get value and make the new max. auto bindIt = it->second.begin();
float_t inputValue = this->getInputValue(*bindIt); while(bindIt != it->second.end()) {
value = mathMax<float_t>(value, inputValue); // Get value and make the new max.
++bindIt; float_t inputValue = this->getInputValue(*bindIt);
} value = mathMax<float_t>(value, inputValue);
++bindIt;
// Set into current values }
if(this->currentIsLeft) {
this->valuesLeft[it->first] = value; // Set into current values
} else { if(this->currentIsLeft) {
this->valuesRight[it->first] = value; this->valuesLeft[it->first] = value;
} } else {
++it; this->valuesRight[it->first] = value;
} }
++it;
// TODO: trigger events }
}
}; // TODO: trigger events
}
};
} }

View File

@ -1,40 +1,42 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "Scene.hpp" #include "Scene.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
Scene::Scene(DawnGame &game) : game(game) { Scene::Scene(DawnGame *game) {
this->nextId = 0; this->game = game;
} this->nextId = 0;
}
void Scene::update() {
// Finsh adding scene items that were trying to add from the last frame. void Scene::update() {
auto it = this->itemsNotInitialized.begin(); // Finsh adding scene items that were trying to add from the last frame.
while(it != this->itemsNotInitialized.end()) { auto it = this->itemsNotInitialized.begin();
this->items[it->first] = it->second; while(it != this->itemsNotInitialized.end()) {
it->second->init(); this->items[it->first] = it->second;
++it; it->second->init();
} ++it;
this->itemsNotInitialized.clear(); }
this->itemsNotInitialized.clear();
// TODO: Cleanup old scene items
// TODO: Cleanup old scene items
// TODO: Tick scene items(?)
this->eventSceneUpdate.invoke(); // TODO: Tick scene items(?)
if(!this->game.timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke(); this->eventSceneUpdate.invoke();
} if(!this->game->timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke();
}
std::shared_ptr<SceneItem> Scene::createSceneItem() {
sceneitemid_t id = this->nextId++; SceneItem * Scene::createSceneItem() {
auto item = std::make_shared<SceneItem>(*this, id); sceneitemid_t id = this->nextId++;
this->itemsNotInitialized[id] = item; auto item = new SceneItem(this, id);
return item; this->itemsNotInitialized[id] = item;
} return item;
}
Scene::~Scene() {
Scene::~Scene() {
} }

View File

@ -1,87 +1,87 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "SceneItem.hpp" #include "SceneItem.hpp"
#include "event/Event.hpp" #include "event/Event.hpp"
namespace Dawn { namespace Dawn {
class DawnGame; class DawnGame;
class Scene { class Scene {
private: private:
sceneitemid_t nextId; sceneitemid_t nextId;
std::map<sceneitemid_t, std::shared_ptr<SceneItem>> items; std::map<sceneitemid_t, SceneItem*> items;
std::map<sceneitemid_t, std::shared_ptr<SceneItem>> itemsNotInitialized; std::map<sceneitemid_t, SceneItem*> itemsNotInitialized;
public: public:
DawnGame &game; DawnGame *game;
Event<> eventSceneUpdate; Event<> eventSceneUpdate;
Event<> eventSceneUnpausedUpdate; Event<> eventSceneUnpausedUpdate;
/** /**
* Construct a new Scene instance. * Construct a new Scene instance.
* *
* @param game Reference to the game that this scene belongs to. * @param game Reference to the game that this scene belongs to.
*/ */
Scene(DawnGame &game); Scene(DawnGame *game);
/** /**
* Perform a one frame synchronous tick on the current scene. This may * Perform a one frame synchronous tick on the current scene. This may
* change in future to be more event-like. * change in future to be more event-like.
*/ */
void update(); void update();
/** /**
* Create a Scene Item object and add to the current scene. * Create a Scene Item object and add to the current scene.
* *
* @return A shared pointer to the created SceneItem. * @return A shared pointer to the created SceneItem.
*/ */
std::shared_ptr<SceneItem> createSceneItem(); SceneItem * createSceneItem();
/** /**
* Finds an existing component on the scene (Root Level Only) that has a * Finds an existing component on the scene (Root Level Only) that has a
* component matching the given component type. Returns nullptr if no item * component matching the given component type. Returns nullptr if no item
* with the specified component could be found. * with the specified component could be found.
* *
* @tparam Component type to look for. * @tparam Component type to look for.
* @return Pointer to the found component (and by extension the item). * @return Pointer to the found component (and by extension the item).
*/ */
template<class T> template<class T>
std::shared_ptr<T> findComponent() { T * findComponent() {
auto it = this->items.begin(); auto it = this->items.begin();
while(it != this->items.end()) { while(it != this->items.end()) {
auto component = it->second->getComponent<T>(); auto component = it->second->getComponent<T>();
if(component != nullptr) return component; if(component != nullptr) return component;
++it; ++it;
} }
return nullptr; return nullptr;
} }
/** /**
* Finds all exisitng components on the scene (Root Level Only) that has a * Finds all exisitng components on the scene (Root Level Only) that has a
* matching component of the given component type. * matching component of the given component type.
* *
* @tparam Component type to look for. * @tparam Component type to look for.
* @return List of matching compnoents. * @return List of matching compnoents.
*/ */
template<class T> template<class T>
std::vector<std::shared_ptr<T>> findComponents() { std::vector<T*> findComponents() {
std::vector<std::shared_ptr<T>> components; std::vector<T*> components;
auto it = this->items.begin(); auto it = this->items.begin();
while(it != this->items.end()) { while(it != this->items.end()) {
auto component = it->second->getComponent<T>(); auto component = it->second->getComponent<T>();
if(component != nullptr) components.push_back(component); if(component != nullptr) components.push_back(component);
++it; ++it;
} }
return components; return components;
} }
/** /**
* Destroys a previously initialized Scene. * Destroys a previously initialized Scene.
*/ */
~Scene(); ~Scene();
}; };
} }

View File

@ -1,59 +1,57 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "SceneItem.hpp" #include "SceneItem.hpp"
#include "Scene.hpp" #include "Scene.hpp"
using namespace Dawn; using namespace Dawn;
SceneItem::SceneItem(Scene &scene, sceneitemid_t id) : SceneItem::SceneItem(Scene *scene, sceneitemid_t id) : transform(this) {
scene(scene), this->id = id;
id(id), this->scene = scene;
transform(*this) }
{
} void SceneItem::init() {
// Keep checking all components until they have all inited
void SceneItem::init() { int32_t waitingOn;
// Keep checking all components until they have all inited do {
int32_t waitingOn; waitingOn = 0;
do {
waitingOn = 0; // For each component
auto it = this->components.begin();
// For each component while(it != this->components.end()) {
auto it = this->components.begin(); // Has this component already inited?
while(it != this->components.end()) { if((*it)->hasInitialized) {
// Has this component already inited? ++it;
if((*it)->hasInitialized) { continue;
++it; }
continue;
} // For each dependency.
auto deps = (*it)->getDependencies();
// For each dependency. bool_t waiting = false;
auto deps = (*it)->getDependencies(); auto it2 = deps.begin();
bool_t waiting = false; while(it2 != deps.end()) {
auto it2 = deps.begin(); // Has the dep not yet inited?
while(it2 != deps.end()) { if(!(*it2)->hasInitialized) {
// Has the dep not yet inited? waiting = true;
if(!(*it2)->hasInitialized) { break;
waiting = true; }
break; ++it2;
} }
++it2;
} // Are we waiting for a dep?
if(waiting) {
// Are we waiting for a dep? waitingOn++;
if(waiting) { } else {
waitingOn++; (*it)->init();
} else { }
(*it)->init(); ++it;
} }
++it; } while(waitingOn != 0);
} }
} while(waitingOn != 0);
} SceneItem::~SceneItem() {
std::cout << "Scene item disposed" << std::endl;
SceneItem::~SceneItem() {
std::cout << "Scene item disposed" << std::endl;
} }

View File

@ -1,117 +1,117 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "SceneItemComponent.hpp" #include "SceneItemComponent.hpp"
#include "display/Transform.hpp" #include "display/Transform.hpp"
#include "event/Event.hpp" #include "event/Event.hpp"
namespace Dawn { namespace Dawn {
typedef int32_t sceneitemid_t; typedef int32_t sceneitemid_t;
class Scene; class Scene;
class SceneItem { class SceneItem {
private: private:
std::vector<std::shared_ptr<SceneItemComponent>> components; std::vector<SceneItemComponent*> components;
public: public:
Scene &scene; Scene *scene;
sceneitemid_t id; sceneitemid_t id;
Transform transform; Transform transform;
/** /**
* Constructor for a SceneItem. Scene Items should only be called and * Constructor for a SceneItem. Scene Items should only be called and
* initialized by the scene itself. * initialized by the scene itself.
* *
* @param scene Weak pointer to the Scene that this SceneItem belongs to. * @param scene Weak pointer to the Scene that this SceneItem belongs to.
* @param id Scene Item ID that the Scene assigned this SceneItem. * @param id Scene Item ID that the Scene assigned this SceneItem.
*/ */
SceneItem(Scene &scene, sceneitemid_t id); SceneItem(Scene *scene, sceneitemid_t id);
/** /**
* Called by the Scene the frame after we were constructed so we can begin * Called by the Scene the frame after we were constructed so we can begin
* existing. * existing.
*/ */
void init(); void init();
/** /**
* Adds a component to this scene item. Components will only have their * Adds a component to this scene item. Components will only have their
* init methods invoked on the first frame we enter the scene. If you add * init methods invoked on the first frame we enter the scene. If you add
* a component to this item after this time you will either need to try * a component to this item after this time you will either need to try
* manually invoking its' init method, or ensure the component is aware of * manually invoking its' init method, or ensure the component is aware of
* the entire SceneItem lifecycle and listen for added callbacks. * the entire SceneItem lifecycle and listen for added callbacks.
* *
* @tparam T Type of component being added to this scene item. * @tparam T Type of component being added to this scene item.
* @return A shared pointer to the newly added component. * @return A shared pointer to the newly added component.
*/ */
template<class T> template<class T>
std::shared_ptr<T> addComponent() { T * addComponent() {
auto component = std::make_shared<T>(*this); auto component = new T(this);
this->components.push_back(component); this->components.push_back(component);
return component; return component;
} }
/** /**
* Returns a component attached to this SceneItem. This method will return * Returns a component attached to this SceneItem. This method will return
* either a shared pointer to the component, or nullptr if the item does * either a shared pointer to the component, or nullptr if the item does
* not have the queried component. * not have the queried component.
* *
* @tparam T Type of component to be fetched. * @tparam T Type of component to be fetched.
* @return A shared pointer to the component, or nullptr if not found. * @return A shared pointer to the component, or nullptr if not found.
*/ */
template<class T> template<class T>
std::shared_ptr<T> getComponent() { T * getComponent() {
auto it = this->components.begin(); auto it = this->components.begin();
while(it != this->components.end()) { while(it != this->components.end()) {
auto castedAs = std::dynamic_pointer_cast<T>(*it); T *castedAs = dynamic_cast<T*>(*it);
if(castedAs != nullptr) return castedAs; if(castedAs != nullptr) return castedAs;
++it; ++it;
} }
return nullptr; return nullptr;
} }
/** /**
* Finds a (direct) child of this component that has a matching component. * Finds a (direct) child of this component that has a matching component.
* *
* @tparam T Component to find child of. * @tparam T Component to find child of.
* @return Pointer to the child, or nullptr if not found. * @return Pointer to the child, or nullptr if not found.
*/ */
template<class T> template<class T>
std::shared_ptr<T> findChild() { T * findChild() {
auto it = this->transform.children.begin(); auto it = this->transform.children.begin();
while(it != this->transform.children.end()) { while(it != this->transform.children.end()) {
auto child = (*it)->item.getComponent<T>(); auto child = (*it)->item->getComponent<T>();
if(child != nullptr) return child; if(child != nullptr) return child;
++it; ++it;
} }
return nullptr; return nullptr;
} }
/** /**
* Finds all (direct) children of this component that match the queried * Finds all (direct) children of this component that match the queried
* component. * component.
* *
* @tparam T Component to find children for. * @tparam T Component to find children for.
* @return Array of pointers to matching children. * @return Array of pointers to matching children.
*/ */
template<class T> template<class T>
std::vector<std::shared_ptr<T>> findChildren() { std::vector<T*> findChildren() {
auto it = this->transform.children.begin(); auto it = this->transform.children.begin();
std::vector<std::shared_ptr<T>> children; std::vector<T*> children;
while(it != this->transform.children.end()) { while(it != this->transform.children.end()) {
auto child = (*it)->item.getComponent<T>(); auto child = (*it)->item->getComponent<T>();
if(child != nullptr) children.push_back(child); if(child != nullptr) children.push_back(child);
++it; ++it;
} }
return children; return children;
} }
/** /**
* Destroy this SceneItem. * Destroy this SceneItem.
*/ */
~SceneItem(); ~SceneItem();
}; };
} }

View File

@ -1,42 +1,41 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "SceneItemComponent.hpp" #include "SceneItemComponent.hpp"
#include "SceneItem.hpp" #include "SceneItem.hpp"
#include "Scene.hpp" #include "Scene.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
SceneItemComponent::SceneItemComponent(SceneItem &item) : SceneItemComponent::SceneItemComponent(SceneItem *item) {
item(item), this->item = item;
transform(item.transform) this->transform = &item->transform;
{ }
}
void SceneItemComponent::init() {
void SceneItemComponent::init() { this->onStart();
this->onStart(); this->hasInitialized = true;
this->hasInitialized = true; }
}
std::vector<SceneItemComponent*> SceneItemComponent::getDependencies() {
std::vector<SceneItemComponent*> SceneItemComponent::getDependencies() { return std::vector<SceneItemComponent*>();
return std::vector<SceneItemComponent*>(); }
}
Scene * SceneItemComponent::getScene() {
Scene & SceneItemComponent::getScene() { return this->item->scene;
return this->item.scene; }
}
DawnGame * SceneItemComponent::getGame() {
DawnGame & SceneItemComponent::getGame() { return this->item->scene->game;
return this->item.scene.game; }
}
void SceneItemComponent::onStart() {
void SceneItemComponent::onStart() {
}
}
SceneItemComponent::~SceneItemComponent() {
SceneItemComponent::~SceneItemComponent() {
} }

View File

@ -1,66 +1,66 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnlibs.hpp" #include "dawnlibs.hpp"
#include "display/Transform.hpp" #include "display/Transform.hpp"
namespace Dawn { namespace Dawn {
class SceneItem; class SceneItem;
class Scene; class Scene;
class DawnGame; class DawnGame;
class SceneItemComponent { class SceneItemComponent {
public: public:
SceneItem &item; SceneItem *item;
Transform &transform; Transform *transform;
bool_t hasInitialized = false; bool_t hasInitialized = false;
/** /**
* Constructs a new SceneItemComponent. Components are attached to * Constructs a new SceneItemComponent. Components are attached to
* SceneItems and will be individual responsibility components, and must * SceneItems and will be individual responsibility components, and must
* communicate to other items/components using methods and events. * communicate to other items/components using methods and events.
* *
* @param item Scene Item thsi component belongs to. * @param item Scene Item thsi component belongs to.
*/ */
SceneItemComponent(SceneItem &item); SceneItemComponent(SceneItem *item);
/** /**
* Requested on the first frame that the parent scene item has become * Requested on the first frame that the parent scene item has become
* active, after all of my dependencies are ready. * active, after all of my dependencies are ready.
*/ */
void init(); void init();
/** /**
* Optionally return all dependencies for this component to wait for init * Optionally return all dependencies for this component to wait for init
* for before the component will be initialized. * for before the component will be initialized.
* *
* @return Array of dependencies. * @return Array of dependencies.
*/ */
virtual std::vector<SceneItemComponent*> getDependencies(); virtual std::vector<SceneItemComponent*> getDependencies();
/** /**
* Shorthand to return the scene that this component's item belongs to. * Shorthand to return the scene that this component's item belongs to.
* @return The current scene. * @return The current scene.
*/ */
Scene & getScene(); Scene * getScene();
/** /**
* Shorthand to return the game that this scene belongs to. * Shorthand to return the game that this scene belongs to.
* @return The current game. * @return The current game.
*/ */
DawnGame & getGame(); DawnGame * getGame();
/** /**
* Same as init, but intended for your subclass to override. * Same as init, but intended for your subclass to override.
*/ */
virtual void onStart(); virtual void onStart();
/** /**
* Cleanup the SceneItemComponent. * Cleanup the SceneItemComponent.
*/ */
virtual ~SceneItemComponent(); virtual ~SceneItemComponent();
}; };
} }

View File

@ -1,80 +1,80 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "Camera.hpp" #include "Camera.hpp"
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
Camera::Camera(SceneItem &item) : Camera::Camera(SceneItem *item) :
SceneItemComponent(item) SceneItemComponent(item)
{ {
this->getRenderTarget().eventRenderTargetResized.addListener( this->getRenderTarget()->eventRenderTargetResized.addListener(
this, &Camera::onRenderTargetResize this, &Camera::onRenderTargetResize
); );
} }
void Camera::updateProjection() { void Camera::updateProjection() {
switch(this->type) { switch(this->type) {
case CAMERA_TYPE_ORTHONOGRAPHIC: case CAMERA_TYPE_ORTHONOGRAPHIC:
this->projection = glm::ortho( this->projection = glm::ortho(
this->orthoLeft, this->orthoLeft,
this->orthoRight, this->orthoRight,
this->orthoBottom, this->orthoBottom,
this->orthoTop, this->orthoTop,
this->clipNear, this->clipNear,
this->clipFar this->clipFar
); );
break; break;
case CAMERA_TYPE_PERSPECTIVE: case CAMERA_TYPE_PERSPECTIVE:
this->projection = glm::perspective( this->projection = glm::perspective(
this->fov, this->fov,
this->getAspect(), this->getAspect(),
this->clipNear, this->clipNear,
this->clipFar this->clipFar
); );
break; break;
} }
} }
RenderTarget & Camera::getRenderTarget() { RenderTarget * Camera::getRenderTarget() {
if(this->target == nullptr) { if(this->target == nullptr) {
return this->getGame().renderManager.getBackBuffer(); return this->getGame()->renderManager.getBackBuffer();
} }
return *this->target; return this->target;
} }
void Camera::setRenderTarget(std::shared_ptr<RenderTarget> renderTarget) { void Camera::setRenderTarget(RenderTarget *renderTarget) {
if(renderTarget == this->target) return; if(renderTarget == this->target) return;
this->getRenderTarget().eventRenderTargetResized.removeListener( this->getRenderTarget()->eventRenderTargetResized.removeListener(
this, &Camera::onRenderTargetResize this, &Camera::onRenderTargetResize
); );
this->target = renderTarget; this->target = renderTarget;
this->getRenderTarget().eventRenderTargetResized.addListener( this->getRenderTarget()->eventRenderTargetResized.addListener(
this, &Camera::onRenderTargetResize this, &Camera::onRenderTargetResize
); );
this->updateProjection(); this->updateProjection();
} }
float_t Camera::getAspect() { float_t Camera::getAspect() {
RenderTarget &target = this->getRenderTarget(); RenderTarget *target = this->getRenderTarget();
return target.getWidth() / target.getHeight(); return target->getWidth() / target->getHeight();
} }
void Camera::onStart() { void Camera::onStart() {
this->updateProjection(); this->updateProjection();
} }
void Camera::onRenderTargetResize(RenderTarget &target, float_t w, float_t h) { void Camera::onRenderTargetResize(RenderTarget *target, float_t w, float_t h) {
this->updateProjection(); this->updateProjection();
} }
Camera::~Camera() { Camera::~Camera() {
this->getRenderTarget().eventRenderTargetResized.removeListener( this->getRenderTarget()->eventRenderTargetResized.removeListener(
this, &Camera::onRenderTargetResize this, &Camera::onRenderTargetResize
); );
} }

View File

@ -1,83 +1,83 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "display/RenderTarget.hpp" #include "display/RenderTarget.hpp"
namespace Dawn { namespace Dawn {
enum CameraType { enum CameraType {
CAMERA_TYPE_ORTHONOGRAPHIC, CAMERA_TYPE_ORTHONOGRAPHIC,
CAMERA_TYPE_PERSPECTIVE CAMERA_TYPE_PERSPECTIVE
}; };
class Camera : public SceneItemComponent { class Camera : public SceneItemComponent {
protected: protected:
std::shared_ptr<RenderTarget> target = nullptr; RenderTarget *target = nullptr;
void onRenderTargetResize(RenderTarget &target, float_t w, float_t h); void onRenderTargetResize(RenderTarget *target, float_t w, float_t h);
public: public:
glm::mat4 projection; glm::mat4 projection;
// Perspective // Perspective
enum CameraType type = CAMERA_TYPE_PERSPECTIVE; enum CameraType type = CAMERA_TYPE_PERSPECTIVE;
float_t fov = 0.785398f;// 45 degrees float_t fov = 0.785398f;// 45 degrees
// Ortho // Ortho
float_t orthoLeft = 0.0f; float_t orthoLeft = 0.0f;
float_t orthoRight = 1.0f; float_t orthoRight = 1.0f;
float_t orthoBottom = 0.0f; float_t orthoBottom = 0.0f;
float_t orthoTop = 1.0f; float_t orthoTop = 1.0f;
// Shared // Shared
float_t clipNear = 0.001f; float_t clipNear = 0.001f;
float_t clipFar = 100.0f; float_t clipFar = 100.0f;
/** /**
* Create a new Camera Component. * Create a new Camera Component.
* *
* @param item SceneItem that this component belongs to. * @param item SceneItem that this component belongs to.
*/ */
Camera(SceneItem &item); Camera(SceneItem *item);
/** /**
* Updates the projection matrix. * Updates the projection matrix.
*/ */
void updateProjection(); void updateProjection();
/** /**
* Returns the intended render target for this camera to render to, will * Returns the intended render target for this camera to render to, will
* automatically revert to the back buffer if no frame buffer is provided. * automatically revert to the back buffer if no frame buffer is provided.
* *
* @return The target render target framebuffer. * @return The target render target framebuffer.
*/ */
RenderTarget & getRenderTarget(); RenderTarget * getRenderTarget();
/** /**
* Updates the render target for the camera to use. * Updates the render target for the camera to use.
* *
* @param renderTarget Render target for this camera to draw to. * @param renderTarget Render target for this camera to draw to.
*/ */
void setRenderTarget(std::shared_ptr<RenderTarget> renderTarget); void setRenderTarget(RenderTarget *renderTarget);
/** /**
* Returs the aspect ratio of the camera. * Returs the aspect ratio of the camera.
* *
* @return The aspect ratio of the camera. * @return The aspect ratio of the camera.
*/ */
float_t getAspect(); float_t getAspect();
/** /**
* Event triggered by the scene item when the item is added to the scene. * Event triggered by the scene item when the item is added to the scene.
*/ */
void onStart() override; void onStart() override;
/** /**
* Disposes a previously initialized camera. * Disposes a previously initialized camera.
*/ */
~Camera(); ~Camera();
}; };
} }

View File

@ -1,72 +1,70 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "Material.hpp" #include "Material.hpp"
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
Material::Material(SceneItem &item) : Material::Material(SceneItem *item) : SceneItemComponent(item) {
SceneItemComponent(item), this->shader = item->scene->game->renderManager.getDefaultShader();
shader(item.scene.game.renderManager.getDefaultShader()) this->updateShaderParameters();
{ }
this->updateShaderParameters();
} void Material::updateShaderParameters() {
this->colorValues.clear();
void Material::updateShaderParameters() { this->boolValues.clear();
this->colorValues.clear();
this->boolValues.clear(); this->parameters = this->shader->getParameters();
this->shader->setDefaultParameters(this);
this->parameters = this->shader->getParameters();
this->shader->setDefaultParameters(*this); // We do need to validate these params at some point to make sure that the
// shader has actually bound them.
// We do need to validate these params at some point to make sure that the }
// shader has actually bound them.
} void Material::setShaderParameters() {
auto it = this->parameters.begin();
void Material::setShaderParameters() { while(it != this->parameters.end()) {
auto it = this->parameters.begin(); switch(it->second) {
while(it != this->parameters.end()) { case SHADER_PARAMETER_TYPE_COLOR:
switch(it->second) { this->shader->setColor(it->first, this->colorValues[it->first]);
case SHADER_PARAMETER_TYPE_COLOR: break;
this->shader->setColor(it->first, this->colorValues[it->first]);
break; case SHADER_PARAMETER_TYPE_MATRIX:
this->shader->setMatrix(it->first, this->matrixValues[it->first]);
case SHADER_PARAMETER_TYPE_MATRIX: break;
this->shader->setMatrix(it->first, this->matrixValues[it->first]);
break; case SHADER_PARAMETER_TYPE_BOOLEAN:
this->shader->setBoolean(it->first, this->boolValues[it->first]);
case SHADER_PARAMETER_TYPE_BOOLEAN: break;
this->shader->setBoolean(it->first, this->boolValues[it->first]);
break; case SHADER_PARAMETER_TYPE_VECTOR3:
this->shader->setVector3(it->first, this->vec3Values[it->first]);
case SHADER_PARAMETER_TYPE_VECTOR3: break;
this->shader->setVector3(it->first, this->vec3Values[it->first]);
break; case SHADER_PARAMETER_TYPE_TEXTURE:
this->shader->setTexture(it->first, this->textureValues[it->first]);
case SHADER_PARAMETER_TYPE_TEXTURE: break;
this->shader->setTexture(it->first, this->textureValues[it->first]);
break; case SHADER_PARAMETER_TYPE_FLOAT:
this->shader->setFloat(it->first, this->floatValues[it->first]);
case SHADER_PARAMETER_TYPE_FLOAT: break;
this->shader->setFloat(it->first, this->floatValues[it->first]);
break; default:
throw "An unsupported or invalid shader parameter type was supplied.";
default: }
throw "An unsupported or invalid shader parameter type was supplied."; ++it;
} }
++it; }
}
} Shader * Material::getShader() {
return this->shader;
std::shared_ptr<Shader> Material::getShader() { }
return this->shader;
} void Material::setShader(Shader * shader) {
this->shader = shader;
void Material::setShader(std::shared_ptr<Shader> shader) { this->updateShaderParameters();
this->shader = shader;
this->updateShaderParameters();
} }

View File

@ -1,63 +1,63 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "display/shader/Shader.hpp" #include "display/shader/Shader.hpp"
namespace Dawn { namespace Dawn {
class Shader; class Shader;
class Material : public SceneItemComponent { class Material : public SceneItemComponent {
private: private:
std::shared_ptr<Shader> shader; Shader *shader;
/** /**
* Internal method that will be invoked to go through and update all of * Internal method that will be invoked to go through and update all of
* the shader parameters whenever the shader is swapped out. * the shader parameters whenever the shader is swapped out.
*/ */
void updateShaderParameters(); void updateShaderParameters();
public: public:
std::map<shaderparameter_t, enum ShaderParameterType> parameters; std::map<shaderparameter_t, enum ShaderParameterType> parameters;
std::map<shaderparameter_t, struct Color> colorValues; std::map<shaderparameter_t, struct Color> colorValues;
std::map<shaderparameter_t, bool_t> boolValues; std::map<shaderparameter_t, bool_t> boolValues;
std::map<shaderparameter_t, glm::mat4> matrixValues; std::map<shaderparameter_t, glm::mat4> matrixValues;
std::map<shaderparameter_t, glm::vec3> vec3Values; std::map<shaderparameter_t, glm::vec3> vec3Values;
std::map<shaderparameter_t, Texture*> textureValues; std::map<shaderparameter_t, Texture*> textureValues;
std::map<shaderparameter_t, float_t> floatValues; std::map<shaderparameter_t, float_t> floatValues;
/** /**
* Material component constructor. * Material component constructor.
* *
* @param item Scene Item this component belongs to. * @param item Scene Item this component belongs to.
*/ */
Material(SceneItem &item); Material(SceneItem *item);
/** /**
* Return the shader this material is currently using. * Return the shader this material is currently using.
* *
* @return Shader pointer to the currently bound shader. * @return Shader pointer to the currently bound shader.
*/ */
std::shared_ptr<Shader> getShader(); Shader * getShader();
/** /**
* Sets the shader for the material to use. This will also clear and * Sets the shader for the material to use. This will also clear and
* update all of the parameters from the shaders' default parameter list. * update all of the parameters from the shaders' default parameter list.
* *
* @param shader Shader to set. * @param shader Shader to set.
*/ */
void setShader(std::shared_ptr<Shader> shader); void setShader(Shader * shader);
/** /**
* Protected method that can be called, likely by the render pipeline, to * Protected method that can be called, likely by the render pipeline, to
* set and update all of the shader parameters from this material on to * set and update all of the shader parameters from this material on to
* the shader. * the shader.
* *
* This method assumes that the shader has already been bound. * This method assumes that the shader has already been bound.
*/ */
void setShaderParameters(); void setShaderParameters();
}; };
} }

View File

@ -1,14 +1,11 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "MeshRenderer.hpp" #include "MeshRenderer.hpp"
using namespace Dawn; using namespace Dawn;
MeshRenderer::MeshRenderer(SceneItem &item) : MeshRenderer::MeshRenderer(SceneItem *item) : SceneItemComponent(item) {
SceneItemComponent(item)
{
} }

View File

@ -1,22 +1,22 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "display/mesh/Mesh.hpp" #include "display/mesh/Mesh.hpp"
namespace Dawn { namespace Dawn {
class MeshRenderer : public SceneItemComponent { class MeshRenderer : public SceneItemComponent {
public: public:
std::shared_ptr<Mesh> mesh = nullptr; Mesh * mesh = nullptr;
/** /**
* Constructs a MeshRenderer scene item component. * Constructs a MeshRenderer scene item component.
* *
* @param item Scene Item this mesh renderer belongs to. * @param item Scene Item this mesh renderer belongs to.
*/ */
MeshRenderer(SceneItem &item); MeshRenderer(SceneItem *item);
}; };
} }

View File

@ -1,52 +1,51 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "UICanvas.hpp" #include "UICanvas.hpp"
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "ui/UIComponent.hpp" #include "ui/UIComponent.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
std::shared_ptr<UICanvas> UICanvas::createCanvas(std::shared_ptr<Scene> scene) { UICanvas * UICanvas::createCanvas(Scene *scene) {
auto item = scene->createSceneItem(); auto item = scene->createSceneItem();
return item->addComponent<UICanvas>(); return item->addComponent<UICanvas>();
} }
UICanvas::UICanvas(SceneItem &item) : SceneItemComponent(item) { UICanvas::UICanvas(SceneItem *item) : SceneItemComponent(item) {
} }
float_t UICanvas::getWidth() { float_t UICanvas::getWidth() {
return this->getGame().renderManager.getBackBuffer().getWidth(); return this->getGame()->renderManager.getBackBuffer()->getWidth();
} }
float_t UICanvas::getHeight() { float_t UICanvas::getHeight() {
return this->getGame().renderManager.getBackBuffer().getHeight(); return this->getGame()->renderManager.getBackBuffer()->getHeight();
} }
void UICanvas::onStart() { void UICanvas::onStart() {
std::cout << "Canvas event" << std::endl; this->getGame()->renderManager.getBackBuffer()->eventRenderTargetResized
this->getGame().renderManager.getBackBuffer() .addListener(this, &UICanvas::onBackBufferResize)
.eventRenderTargetResized.addListener(this, &UICanvas::onBackBufferResize) ;
; }
}
void UICanvas::onBackBufferResize(
void UICanvas::onBackBufferResize( RenderTarget *target,
RenderTarget &target, float_t width,
float_t width, float_t height
float_t height ) {
) { auto it = this->children.begin();
auto it = this->children.begin(); while(it != this->children.end()) {
while(it != this->children.end()) { (*it)->updatePositions();
(*it)->updatePositions(); ++it;
++it; }
} }
}
UICanvas::~UICanvas() {
UICanvas::~UICanvas() { this->getGame()->renderManager.getBackBuffer()->eventRenderTargetResized
this->getGame().renderManager.getBackBuffer() .removeListener(this, &UICanvas::onBackBufferResize)
.eventRenderTargetResized.removeListener(this, &UICanvas::onBackBufferResize) ;
;
} }

View File

@ -1,52 +1,80 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "scene/SceneItemComponent.hpp" #include "scene/SceneItemComponent.hpp"
#include "display/RenderTarget.hpp" #include "display/RenderTarget.hpp"
namespace Dawn { namespace Dawn {
enum UIDrawType { enum UIDrawType {
UI_DRAW_TYPE_WORLD_ABSOLUTE, UI_DRAW_TYPE_WORLD_ABSOLUTE,
UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE, UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE,
UI_DRAW_TYPE_CAMERA_OVERLAY UI_DRAW_TYPE_CAMERA_OVERLAY
}; };
class UIComponent; class UIComponent;
class UICanvas : public SceneItemComponent { class UICanvas : public SceneItemComponent {
protected: protected:
void onBackBufferResize( void onBackBufferResize(
RenderTarget &target, RenderTarget *target,
float_t width, float_t width,
float_t height float_t height
); );
public: public:
static std::shared_ptr<UICanvas> createCanvas( /**
std::shared_ptr<Scene> scene * Creates a UI Canvas Scene Item Element, and attaches it to the provided
); * scene.
*
// * @param scene Scene to create the UI Canvas for.
std::vector<std::shared_ptr<UIComponent>> children; * @return Created UI Canvas.
UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE; */
static UICanvas * createCanvas(Scene *scene);
UICanvas(SceneItem &item);
//
template<class T> std::vector<UIComponent*> children;
std::shared_ptr<T> addElement() { UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
auto item = std::make_shared<T>(*this);
this->children.push_back(item); /**
return item; * Constructs the UI Canvas Scene Item Component.
} *
* @param item Item that this canvas item belongs to.
float_t getWidth(); */
float_t getHeight(); UICanvas(SceneItem *item);
void onStart() override; /**
* Construct and append a UI item to this UI Canvas.
~UICanvas(); *
}; * @tparam Type of the UI Item.
* @return Pointer to the created UI Item.
*/
template<class T>
T * addElement() {
auto item = new T(this);
this->children.push_back(item);
return item;
}
/**
* Returns the width of the root UI Canvas size. In future I may allow
* this to be dynamic, right now it uses the render canvas however.
*
* @return Width of the UI Canvas.
*/
float_t getWidth();
/**
* Returns the height of this UI Canvas element.
*
* @return Height of the UI Canvas.
*/
float_t getHeight();
void onStart() override;
~UICanvas();
};
} }

View File

@ -7,7 +7,7 @@
using namespace Dawn; using namespace Dawn;
UIBorder::UIBorder(UICanvas &canvas) : UIComponent(canvas) { UIBorder::UIBorder(UICanvas *canvas) : UIComponent(canvas) {
this->mesh.createBuffers(QUAD_VERTICE_COUNT * 9, QUAD_INDICE_COUNT * 9); this->mesh.createBuffers(QUAD_VERTICE_COUNT * 9, QUAD_INDICE_COUNT * 9);
this->texture = new Texture(); this->texture = new Texture();
@ -111,12 +111,12 @@ void UIBorder::updatePositions() {
); );
} }
void UIBorder::drawSelf(UIShader &shader, glm::mat4 transform) { void UIBorder::drawSelf(UIShader *shader, glm::mat4 transform) {
if(this->texture == nullptr) return; if(this->texture == nullptr) return;
shader.setUIColor(COLOR_WHITE); shader->setUIColor(COLOR_WHITE);
shader.setUIModel(transform); shader->setUIModel(transform);
shader.setUITexture(this->texture); shader->setUITexture(this->texture);
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1); this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
} }

View File

@ -17,12 +17,12 @@ namespace Dawn {
glm::vec2 uv1 = glm::vec2(1.0f, 1.0f); glm::vec2 uv1 = glm::vec2(1.0f, 1.0f);
void updatePositions() override; void updatePositions() override;
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override; void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
public: public:
Texture *texture; Texture *texture;
UIBorder(UICanvas &canvas); UIBorder(UICanvas *canvas);
/** /**
* Changes the dimensions of the border. * Changes the dimensions of the border.

View File

@ -7,16 +7,15 @@
using namespace Dawn; using namespace Dawn;
UIComponent::UIComponent(UICanvas &canvas) : UIComponent::UIComponent(UICanvas *canvas) {
canvas(canvas) this->canvas = canvas;
{
} }
void UIComponent::updatePositions() { void UIComponent::updatePositions() {
// X Alignment // X Alignment
if(this->alignX == UI_COMPONENT_ALIGN_STRETCH) { if(this->alignX == UI_COMPONENT_ALIGN_STRETCH) {
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->width = this->canvas.getWidth(); this->width = this->canvas->getWidth();
} else { } else {
this->width = this->parent->getWidth(); this->width = this->parent->getWidth();
} }
@ -28,7 +27,7 @@ void UIComponent::updatePositions() {
} else if(this->alignX == UI_COMPONENT_ALIGN_END) { } else if(this->alignX == UI_COMPONENT_ALIGN_END) {
this->width = this->alignment[0]; this->width = this->alignment[0];
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->relativeX = this->canvas.getWidth(); this->relativeX = this->canvas->getWidth();
} else { } else {
this->relativeX = this->parent->getWidth(); this->relativeX = this->parent->getWidth();
} }
@ -37,7 +36,7 @@ void UIComponent::updatePositions() {
} else if(this->alignX == UI_COMPONENT_ALIGN_MIDDLE) { } else if(this->alignX == UI_COMPONENT_ALIGN_MIDDLE) {
this->width = this->alignment[2]; this->width = this->alignment[2];
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->relativeX = this->canvas.getWidth(); this->relativeX = this->canvas->getWidth();
} else { } else {
this->relativeX = this->parent->getWidth(); this->relativeX = this->parent->getWidth();
} }
@ -47,7 +46,7 @@ void UIComponent::updatePositions() {
// Y Alignment // Y Alignment
if(this->alignY == UI_COMPONENT_ALIGN_STRETCH) { if(this->alignY == UI_COMPONENT_ALIGN_STRETCH) {
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->height = this->canvas.getHeight(); this->height = this->canvas->getHeight();
} else { } else {
this->height = this->parent->getHeight(); this->height = this->parent->getHeight();
} }
@ -59,7 +58,7 @@ void UIComponent::updatePositions() {
} else if(this->alignY == UI_COMPONENT_ALIGN_END) { } else if(this->alignY == UI_COMPONENT_ALIGN_END) {
this->height = this->alignment[1]; this->height = this->alignment[1];
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->relativeY = this->canvas.getHeight(); this->relativeY = this->canvas->getHeight();
} else { } else {
this->relativeY = this->parent->getHeight(); this->relativeY = this->parent->getHeight();
} }
@ -68,7 +67,7 @@ void UIComponent::updatePositions() {
} else if(this->alignY == UI_COMPONENT_ALIGN_MIDDLE) { } else if(this->alignY == UI_COMPONENT_ALIGN_MIDDLE) {
this->height = this->alignment[3]; this->height = this->alignment[3];
if(this->parent == nullptr) { if(this->parent == nullptr) {
this->relativeY = this->canvas.getHeight(); this->relativeY = this->canvas->getHeight();
} else { } else {
this->relativeY = this->parent->getHeight(); this->relativeY = this->parent->getHeight();
} }
@ -117,7 +116,7 @@ void UIComponent::setTransform(
this->updatePositions(); this->updatePositions();
} }
void UIComponent::draw(UIShader &uiShader, glm::mat4 parentTransform) { void UIComponent::draw(UIShader *uiShader, glm::mat4 parentTransform) {
// Calculate self transform matrix // Calculate self transform matrix
glm::mat4 selfTransform = parentTransform * glm::translate( glm::mat4 selfTransform = parentTransform * glm::translate(
glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z) glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z)

View File

@ -56,12 +56,12 @@ namespace Dawn {
* @param uiShader UI Shader for the child to use. * @param uiShader UI Shader for the child to use.
* @param selfTransform Self alignment transform. * @param selfTransform Self alignment transform.
*/ */
virtual void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) = 0; virtual void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) = 0;
public: public:
UICanvas &canvas; UICanvas *canvas;
UIComponent(UICanvas &canvas); UIComponent(UICanvas *canvas);
/** /**
* Returns the calculated width, based on the internal alignment values. * Returns the calculated width, based on the internal alignment values.
@ -106,7 +106,7 @@ namespace Dawn {
float_t z float_t z
); );
void draw(UIShader &uiShader, glm::mat4 parentTransform); void draw(UIShader *uiShader, glm::mat4 parentTransform);
/** /**
* Adds a child to this UI Component. * Adds a child to this UI Component.

View File

@ -7,7 +7,7 @@
using namespace Dawn; using namespace Dawn;
UILabel::UILabel(UICanvas &canvas) : UIComponent(canvas) { UILabel::UILabel(UICanvas *canvas) : UIComponent(canvas) {
} }
@ -21,11 +21,14 @@ void UILabel::updateMesh() {
if(this->font == nullptr) return; if(this->font == nullptr) return;
if(this->text.size() == 0) return; if(this->text.size() == 0) return;
float_t width = this->getWidth();
if(width == 0) width = -1;
this->font->buffer( this->font->buffer(
this->text, this->text,
this->fontSize, this->fontSize,
this->getWidth(), width,
this->mesh, &this->mesh,
&this->measure &this->measure
); );
@ -51,15 +54,15 @@ void UILabel::setFontSize(float_t fontSize) {
this->needsRebuffering = true; this->needsRebuffering = true;
} }
void UILabel::drawSelf(UIShader &shader, glm::mat4 selfTransform) { void UILabel::drawSelf(UIShader *shader, glm::mat4 selfTransform) {
if(this->font == nullptr || this->text.size() == 0) return; if(this->font == nullptr || this->text.size() == 0) return;
this->updateMesh(); this->updateMesh();
shader.setUIColor(this->textColor); shader->setUIColor(this->textColor);
shader.setUIModel(selfTransform); shader->setUIModel(selfTransform);
shader.setUITexture(&this->font->getTexture()); shader->setUITexture(this->font->getTexture());
this->font->draw(this->mesh, this->startQuad, this->quadCount); this->font->draw(&this->mesh, this->startQuad, this->quadCount);
} }
void UILabel::setTransform( void UILabel::setTransform(

View File

@ -27,8 +27,8 @@ namespace Dawn {
/** The colour of this label */ /** The colour of this label */
struct Color textColor = COLOR_MAGENTA; struct Color textColor = COLOR_MAGENTA;
UILabel(UICanvas &canvas); UILabel(UICanvas *canvas);
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override; void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
void setTransform( void setTransform(
UIComponentAlign xAlign, UIComponentAlign xAlign,
UIComponentAlign yAlign, UIComponentAlign yAlign,

View File

@ -1,33 +1,33 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "UISprite.hpp" #include "UISprite.hpp"
using namespace Dawn; using namespace Dawn;
UISprite::UISprite(UICanvas &canvas) : UIComponent(canvas) { UISprite::UISprite(UICanvas *canvas) : UIComponent(canvas) {
this->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); this->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
} }
void UISprite::updatePositions() { void UISprite::updatePositions() {
UIComponent::updatePositions(); UIComponent::updatePositions();
QuadMesh::bufferQuadMesh( QuadMesh::bufferQuadMesh(
&this->mesh, &this->mesh,
glm::vec2(0, 0), glm::vec2(0, 0), glm::vec2(0, 0), glm::vec2(0, 0),
glm::vec2(this->width, this->height), glm::vec2(1, 1), glm::vec2(this->width, this->height), glm::vec2(1, 1),
0, 0 0, 0
); );
} }
void UISprite::drawSelf(UIShader &uiShader, glm::mat4 selfTransform) { void UISprite::drawSelf(UIShader *uiShader, glm::mat4 selfTransform) {
uiShader.setUITexture(nullptr); uiShader->setUITexture(nullptr);
uiShader.setUIModel(selfTransform); uiShader->setUIModel(selfTransform);
uiShader.setUIModel(glm::mat4(1.0f)); uiShader->setUIModel(glm::mat4(1.0f));
uiShader.setUIColor(COLOR_WHITE); uiShader->setUIColor(COLOR_WHITE);
uiShader.setUITexture(this->texture); uiShader->setUITexture(this->texture);
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1); this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
} }

View File

@ -12,7 +12,7 @@ namespace Dawn {
class UISprite : public UIComponent { class UISprite : public UIComponent {
protected: protected:
void updatePositions() override; void updatePositions() override;
void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) override; void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) override;
public: public:
Mesh mesh; Mesh mesh;
@ -23,6 +23,6 @@ namespace Dawn {
* *
* @param canvas Canvas that this sprite belongs to. * @param canvas Canvas that this sprite belongs to.
*/ */
UISprite(UICanvas &canvas); UISprite(UICanvas *canvas);
}; };
} }

View File

@ -8,7 +8,7 @@
using namespace Dawn; using namespace Dawn;
VisualNovelTextbox::VisualNovelTextbox(UICanvas &canvas) : VisualNovelTextbox::VisualNovelTextbox(UICanvas *canvas) :
UIComponent(canvas), UIComponent(canvas),
border(canvas), border(canvas),
label(canvas) label(canvas)
@ -21,7 +21,7 @@ VisualNovelTextbox::VisualNovelTextbox(UICanvas &canvas) :
this->label.startQuad = 0; this->label.startQuad = 0;
this->label.quadCount = 0; this->label.quadCount = 0;
this->canvas.getScene().eventSceneUnpausedUpdate.addListener( this->canvas->getScene()->eventSceneUnpausedUpdate.addListener(
this, &VisualNovelTextbox::textboxOnSceneUpdate this, &VisualNovelTextbox::textboxOnSceneUpdate
); );
} }
@ -53,15 +53,15 @@ void VisualNovelTextbox::updatePositions() {
} }
void VisualNovelTextbox::textboxOnSceneUpdate() { void VisualNovelTextbox::textboxOnSceneUpdate() {
DawnGame &game = this->canvas.getGame(); DawnGame *game = this->canvas->getGame();
if(this->hasRevealedAllCurrentCharacters()) { if(this->hasRevealedAllCurrentCharacters()) {
if(this->hasRevealedAllCharacters()) { if(this->hasRevealedAllCharacters()) {
if(game.inputManager.isPressed(INPUT_BIND_ACCEPT)) { if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
this->eventClose.invoke(); this->eventClose.invoke();
} }
} else { } else {
if(game.inputManager.isPressed(INPUT_BIND_ACCEPT)) { if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
this->lineCurrent += this->getCountOfVisibleLines(); this->lineCurrent += this->getCountOfVisibleLines();
this->label.startQuad = 0; this->label.startQuad = 0;
for(int32_t i = 0; i < this->lineCurrent; i++) { for(int32_t i = 0; i < this->lineCurrent; i++) {
@ -90,10 +90,10 @@ void VisualNovelTextbox::textboxOnSceneUpdate() {
} }
auto lastTimeCharacter = (int32_t)mathFloorFloat(this->timeCharacter); auto lastTimeCharacter = (int32_t)mathFloorFloat(this->timeCharacter);
if(game.inputManager.isDown(INPUT_BIND_ACCEPT)) { if(game->inputManager.isDown(INPUT_BIND_ACCEPT)) {
this->timeCharacter += game.timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED_FASTER; this->timeCharacter += game->timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED_FASTER;
} else { } else {
this->timeCharacter += game.timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED; this->timeCharacter += game->timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED;
} }
auto newTimeCharacter = (int32_t)mathFloorFloat(this->timeCharacter); auto newTimeCharacter = (int32_t)mathFloorFloat(this->timeCharacter);
if(newTimeCharacter == lastTimeCharacter) return; if(newTimeCharacter == lastTimeCharacter) return;
@ -114,7 +114,7 @@ int32_t VisualNovelTextbox::getCountOfVisibleLines() {
return this->label.measure.getLineCount(); return this->label.measure.getLineCount();
} }
void VisualNovelTextbox::drawSelf(UIShader &shader, glm::mat4 self) {} void VisualNovelTextbox::drawSelf(UIShader *shader, glm::mat4 self) {}
void VisualNovelTextbox::setBorder(Texture *texture, glm::vec2 dimensions) { void VisualNovelTextbox::setBorder(Texture *texture, glm::vec2 dimensions) {
this->border.texture = texture; this->border.texture = texture;
@ -156,7 +156,7 @@ bool_t VisualNovelTextbox::hasRevealedAllCharacters() {
} }
VisualNovelTextbox::~VisualNovelTextbox() { VisualNovelTextbox::~VisualNovelTextbox() {
this->canvas.getScene().eventSceneUnpausedUpdate.removeListener( this->canvas->getScene()->eventSceneUnpausedUpdate.removeListener(
this, &VisualNovelTextbox::textboxOnSceneUpdate this, &VisualNovelTextbox::textboxOnSceneUpdate
); );
} }

View File

@ -22,7 +22,7 @@ namespace Dawn {
float_t timeCharacter = 0.0f; float_t timeCharacter = 0.0f;
void updatePositions() override; void updatePositions() override;
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override; void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
/** /**
* Listens for scene updates. * Listens for scene updates.
@ -44,17 +44,12 @@ namespace Dawn {
Event<> eventAllCharactersRevealed; Event<> eventAllCharactersRevealed;
Event<> eventClose; Event<> eventClose;
VisualNovelTextbox(UICanvas &canvas); VisualNovelTextbox(UICanvas *canvas);
void setFont(Font *font); void setFont(Font *font);
void setBorder(Texture *texture, glm::vec2 dimensions); void setBorder(Texture *texture, glm::vec2 dimensions);
void setText(std::string text, float_t fontSize); void setText(std::string text, float_t fontSize);
bool_t hasRevealedAllCurrentCharacters(); bool_t hasRevealedAllCurrentCharacters();
bool_t hasRevealedAllCharacters(); bool_t hasRevealedAllCharacters();
~VisualNovelTextbox(); ~VisualNovelTextbox();
}; };
} }

View File

@ -1,172 +1,172 @@
/** /**
* Copyright (c) 2022 Dominic Masters * Copyright (c) 2022 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
*/ */
#include "DawnGLFWHost.hpp" #include "DawnGLFWHost.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "display/BackBufferRenderTarget.hpp" #include "display/BackBufferRenderTarget.hpp"
using namespace Dawn; using namespace Dawn;
// Static declaration of the host, needed due to GLFW events being C-like // Static declaration of the host, needed due to GLFW events being C-like
DawnHost *DAWN_HOST = nullptr; DawnHost *DAWN_HOST = nullptr;
// Host // Host
DawnHost::DawnHost() { DawnHost::DawnHost() {
this->data = std::make_unique<DawnHostData>(); this->data = new DawnHostData();
this->data->window = nullptr; this->data->window = nullptr;
} }
int32_t DawnHost::init(DawnGame &game) { int32_t DawnHost::init(DawnGame *game) {
// Update values // Update values
this->game = &game; this->game = game;
DAWN_HOST = this; DAWN_HOST = this;
// Init GLFW // Init GLFW
if(!glfwInit()) return DAWN_GLFW_INIT_RESULT_INIT_FAILED; if(!glfwInit()) return DAWN_GLFW_INIT_RESULT_INIT_FAILED;
glfwSetErrorCallback(&glfwOnError); glfwSetErrorCallback(&glfwOnError);
// Setup window hints // Setup window hints
glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false); glfwWindowHint(GLFW_OPENGL_DEBUG_CONTEXT, false);
// Create Window // Create Window
this->data->window = glfwCreateWindow( this->data->window = glfwCreateWindow(
DAWN_GLFW_WINDOW_WIDTH_DEFAULT, DAWN_GLFW_WINDOW_WIDTH_DEFAULT,
DAWN_GLFW_WINDOW_HEIGHT_DEFAULT, DAWN_GLFW_WINDOW_HEIGHT_DEFAULT,
"Dawn", NULL, NULL "Dawn", NULL, NULL
); );
if(this->data->window == nullptr) { if(this->data->window == nullptr) {
glfwTerminate(); glfwTerminate();
return DAWN_GLFW_INIT_RESULT_WINDOW_CREATE_FAILED; return DAWN_GLFW_INIT_RESULT_WINDOW_CREATE_FAILED;
} }
// Load GLAD // Load GLAD
glfwMakeContextCurrent(this->data->window); glfwMakeContextCurrent(this->data->window);
glfwSwapInterval(0); glfwSwapInterval(0);
gladLoadGLLoader((GLADloadproc)glfwGetProcAddress); gladLoadGLLoader((GLADloadproc)glfwGetProcAddress);
// Override the defaults // Override the defaults
game.renderManager.backBuffer.setSize( game->renderManager.backBuffer.setSize(
DAWN_GLFW_WINDOW_WIDTH_DEFAULT, DAWN_GLFW_WINDOW_WIDTH_DEFAULT,
DAWN_GLFW_WINDOW_HEIGHT_DEFAULT DAWN_GLFW_WINDOW_HEIGHT_DEFAULT
); );
// Default keybinds // Default keybinds
game.inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_ENTER); game->inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_ENTER);
game.inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_E); game->inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_E);
game.inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_SPACE); game->inputManager.bind(INPUT_BIND_ACCEPT, GLFW_KEY_SPACE);
// Initialize the game // Initialize the game
auto result = game.init(); auto result = game->init();
if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result; if(result != DAWN_GAME_INIT_RESULT_SUCCESS) return result;
// Set up event listeners // Set up event listeners
glfwSetWindowSizeCallback(this->data->window, &glfwOnResize); glfwSetWindowSizeCallback(this->data->window, &glfwOnResize);
glfwSetKeyCallback(this->data->window, &glfwOnKey); glfwSetKeyCallback(this->data->window, &glfwOnKey);
return DAWN_HOST_INIT_RESULT_SUCCESS; return DAWN_HOST_INIT_RESULT_SUCCESS;
} }
int32_t DawnHost::start(DawnGame &game) { int32_t DawnHost::start(DawnGame *game) {
double_t time, newTime; double_t time, newTime;
float_t fDelta; float_t fDelta;
int32_t updateResult; int32_t updateResult;
// Main Render Loop // Main Render Loop
time = 0.0f; time = 0.0f;
while(!glfwWindowShouldClose(this->data->window)) { while(!glfwWindowShouldClose(this->data->window)) {
// Determine the delta. // Determine the delta.
newTime = glfwGetTime(); newTime = glfwGetTime();
fDelta = (float_t)(newTime - time); fDelta = (float_t)(newTime - time);
time = newTime; time = newTime;
// Perform update // Perform update
updateResult = this->update(game, fDelta); updateResult = this->update(game, fDelta);
// Did the update complete successfully? // Did the update complete successfully?
if(updateResult == DAWN_HOST_UPDATE_RESULT_EXIT) { if(updateResult == DAWN_HOST_UPDATE_RESULT_EXIT) {
break; break;
} else if(updateResult != DAWN_HOST_UPDATE_RESULT_SUCCESS) { } else if(updateResult != DAWN_HOST_UPDATE_RESULT_SUCCESS) {
return DAWN_GLFW_START_RESULT_UPDATE_FAILED; return DAWN_GLFW_START_RESULT_UPDATE_FAILED;
} }
// Tick the engine. // Tick the engine.
glfwSwapBuffers(this->data->window); glfwSwapBuffers(this->data->window);
// Update events // Update events
glfwPollEvents(); glfwPollEvents();
} }
return DAWN_HOST_START_RESULT_EXIT_SUCCESS; return DAWN_HOST_START_RESULT_EXIT_SUCCESS;
} }
int32_t DawnHost::update(DawnGame &game, float_t delta) { int32_t DawnHost::update(DawnGame *game, float_t delta) {
auto ret = game.update(delta); auto ret = game->update(delta);
switch(ret) { switch(ret) {
case DAWN_GAME_UPDATE_RESULT_SUCCESS: case DAWN_GAME_UPDATE_RESULT_SUCCESS:
return DAWN_HOST_UPDATE_RESULT_SUCCESS; return DAWN_HOST_UPDATE_RESULT_SUCCESS;
case DAWN_GAME_UPDATE_RESULT_EXIT: case DAWN_GAME_UPDATE_RESULT_EXIT:
return DAWN_HOST_UPDATE_RESULT_EXIT; return DAWN_HOST_UPDATE_RESULT_EXIT;
default: default:
return ret; return ret;
} }
} }
void DawnHost::unload(DawnGame &game) { void DawnHost::unload(DawnGame *game) {
glfwDestroyWindow(this->data->window); glfwDestroyWindow(this->data->window);
this->data->window = nullptr; this->data->window = nullptr;
glfwTerminate(); glfwTerminate();
} }
DawnHost::~DawnHost() { DawnHost::~DawnHost() {
DAWN_HOST = nullptr; DAWN_HOST = nullptr;
} }
// GLFW Callbacks // GLFW Callbacks
void glfwOnError(int error, const char* description) { void glfwOnError(int error, const char* description) {
fputs(description, stderr); fputs(description, stderr);
} }
void glfwOnResize( void glfwOnResize(
GLFWwindow *window, GLFWwindow *window,
int32_t width, int32_t width,
int32_t height int32_t height
) { ) {
if(DAWN_HOST == nullptr) return; if(DAWN_HOST == nullptr) return;
// TODO: I may throttle this, it calls for every frame the window's resized. // TODO: I may throttle this, it calls for every frame the window's resized.
DAWN_HOST->game->renderManager.backBuffer.setSize( DAWN_HOST->game->renderManager.backBuffer.setSize(
(float_t)width, (float_t)width,
(float_t)height (float_t)height
); );
} }
void glfwOnKey( void glfwOnKey(
GLFWwindow *window, GLFWwindow *window,
int32_t key, int32_t key,
int32_t scancode, int32_t scancode,
int32_t action, int32_t action,
int32_t mods int32_t mods
) { ) {
if(DAWN_HOST == nullptr) return; if(DAWN_HOST == nullptr) return;
// Determine Value // Determine Value
float_t value; float_t value;
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
value = 1.0f; value = 1.0f;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
value = 0.0f; value = 0.0f;
} else { } else {
return; return;
} }
// Determine the input axis // Determine the input axis
DAWN_HOST->game->inputManager.rawInputValues[key] = value; DAWN_HOST->game->inputManager.rawInputValues[key] = value;
} }

View File

@ -1,20 +1,20 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "InputManager.hpp" #include "InputManager.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
using namespace Dawn; using namespace Dawn;
InputManager::InputManager(DawnGame &game) : IInputManager<int32_t>(game) { InputManager::InputManager(DawnGame *game) : IInputManager<int32_t>(game) {
} }
float_t InputManager::getInputValue(int32_t axis) { float_t InputManager::getInputValue(int32_t axis) {
auto exist = this->rawInputValues.find(axis); auto exist = this->rawInputValues.find(axis);
if(exist == this->rawInputValues.end()) return 0.0f; if(exist == this->rawInputValues.end()) return 0.0f;
return exist->second; return exist->second;
} }

View File

@ -1,19 +1,19 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "input/_InputManager.hpp" #include "input/_InputManager.hpp"
namespace Dawn { namespace Dawn {
class InputManager : public IInputManager<int32_t> { class InputManager : public IInputManager<int32_t> {
protected: protected:
float_t getInputValue(int32_t axis) override; float_t getInputValue(int32_t axis) override;
public: public:
std::map<int32_t, float_t> rawInputValues; std::map<int32_t, float_t> rawInputValues;
InputManager(DawnGame &game); InputManager(DawnGame *game);
}; };
} }

View File

@ -1,42 +1,45 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "DawnHostWin32.hpp" #include "DawnHostWin32.hpp"
using namespace Dawn; using namespace Dawn;
int32_t main(int32_t argc, char **args) { int32_t main(int32_t argc, char **args) {
int32_t result; int32_t result;
// Create the host // Create the host
auto host = std::make_shared<DawnHost>(); auto host = new DawnHost();
auto game = std::make_shared<DawnGame>(*host); auto game = new DawnGame(host);
// Initialize the host and error check // Initialize the host and error check
result = host->init(*game); result = host->init(game);
switch(result) { switch(result) {
case DAWN_HOST_INIT_RESULT_SUCCESS: case DAWN_HOST_INIT_RESULT_SUCCESS:
break; break;
default: default:
return result; return result;
} }
// Request the main loop to start running. // Request the main loop to start running.
result = host->start(*game); result = host->start(game);
switch(result) { switch(result) {
case DAWN_HOST_START_RESULT_SUCCESS: case DAWN_HOST_START_RESULT_SUCCESS:
break; break;
case DAWN_HOST_START_RESULT_EXIT_SUCCESS: case DAWN_HOST_START_RESULT_EXIT_SUCCESS:
break; break;
default: default:
return result; return result;
} }
// Main loop finished without errors, cleanup // Main loop finished without errors, cleanup
host->unload(*game); host->unload(game);
// Success delete game;
return 0; delete host;
// Success
return 0;
} }

View File

@ -1,48 +1,48 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "BackBufferRenderTarget.hpp" #include "BackBufferRenderTarget.hpp"
using namespace Dawn; using namespace Dawn;
BackBufferRenderTarget::BackBufferRenderTarget(RenderManager &renderManager) : BackBufferRenderTarget::BackBufferRenderTarget(RenderManager &renderManager) :
renderManager(renderManager) renderManager(renderManager)
{ {
} }
float_t BackBufferRenderTarget::getWidth() { float_t BackBufferRenderTarget::getWidth() {
return this->width; return this->width;
} }
float_t BackBufferRenderTarget::getHeight() { float_t BackBufferRenderTarget::getHeight() {
return this->height; return this->height;
} }
void BackBufferRenderTarget::setSize(float_t width, float_t height) { void BackBufferRenderTarget::setSize(float_t width, float_t height) {
if(this->width == width && this->height == height) return; if(this->width == width && this->height == height) return;
this->width = width; this->width = width;
this->height = height; this->height = height;
this->eventRenderTargetResized.invoke(*this, width, height); this->eventRenderTargetResized.invoke(this, width, height);
} }
void BackBufferRenderTarget::setClearColor(struct Color color) { void BackBufferRenderTarget::setClearColor(struct Color color) {
this->clearColor = color; this->clearColor = color;
} }
void BackBufferRenderTarget::clear(flag8_t clearFlags) { void BackBufferRenderTarget::clear(flag8_t clearFlags) {
glClearColor( glClearColor(
this->clearColor.r, this->clearColor.r,
this->clearColor.g, this->clearColor.g,
this->clearColor.b, this->clearColor.b,
this->clearColor.a this->clearColor.a
); );
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
void BackBufferRenderTarget::bind() { void BackBufferRenderTarget::bind() {
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
glViewport(0, 0, (GLsizei)this->width, (GLsizei)this->height); glViewport(0, 0, (GLsizei)this->width, (GLsizei)this->height);
} }

View File

@ -1,73 +1,74 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "game/DawnGame.hpp" #include "game/DawnGame.hpp"
#include "display/RenderManager.hpp" #include "display/RenderManager.hpp"
#include "display/StandardRenderPipeline.hpp" #include "display/StandardRenderPipeline.hpp"
using namespace Dawn; using namespace Dawn;
RenderManager::RenderManager(DawnGame &game) : RenderManager::RenderManager(DawnGame *game) :
IRenderManager(game), IRenderManager(game),
backBuffer(*this) backBuffer(*this)
{ {
this->standardRenderPipeline=std::make_shared<StandardRenderPipeline>(*this); this->standardRenderPipeline = new StandardRenderPipeline(this);
this->simpleShader = std::make_shared<SimpleTexturedShader>(); this->simpleShader = new SimpleTexturedShader();
this->uiShader = std::make_shared<UIShader>(); this->uiShader = new UIShader();
} }
void RenderManager::init() { void RenderManager::init() {
this->standardRenderPipeline->init(); this->standardRenderPipeline->init();
this->simpleShader->compile(); this->simpleShader->compile();
this->uiShader->compile(); this->uiShader->compile();
// Prepare the initial values
// Prepare the initial values glEnable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_2D); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glDepthMask(GL_TRUE);
glDepthMask(GL_TRUE); glDepthFunc(GL_LESS);
glDepthFunc(GL_LESS); }
}
RenderTarget * RenderManager::getBackBuffer() {
RenderTarget & RenderManager::getBackBuffer() { return &this->backBuffer;
return this->backBuffer; }
}
RenderPipeline * RenderManager::getRenderPipeline() {
RenderPipeline & RenderManager::getRenderPipeline() { return this->standardRenderPipeline;
return *this->standardRenderPipeline; }
}
Shader * RenderManager::getDefaultShader() {
std::shared_ptr<Shader> RenderManager::getDefaultShader() { return this->simpleShader;
return this->simpleShader; }
}
UIShader * RenderManager::getUIShader() {
std::shared_ptr<UIShader> RenderManager::getUIShader() { return this->uiShader;
return this->uiShader; }
}
void RenderManager::setRenderFlags(renderflag_t flags) {
void RenderManager::setRenderFlags(renderflag_t flags) { this->renderFlags = flags;
this->renderFlags = flags;
if((flags & RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST) == 0) {
if((flags & RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST) == 0) { glDisable(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST); } else {
} else { glEnable(GL_DEPTH_TEST);
glEnable(GL_DEPTH_TEST); }
}
if((flags & RENDER_MANAGER_RENDER_FLAG_BLEND) == 0) {
if((flags & RENDER_MANAGER_RENDER_FLAG_BLEND) == 0) { glDisable(GL_BLEND);
glDisable(GL_BLEND); } else {
} else { glEnable(GL_BLEND);
glEnable(GL_BLEND); }
} }
}
void RenderManager::update() {
void RenderManager::update() { this->getRenderPipeline()->render();
this->getRenderPipeline().render(); }
}
RenderManager::~RenderManager() {
RenderManager::~RenderManager() { delete this->standardRenderPipeline;
delete this->simpleShader;
delete this->uiShader;
} }

View File

@ -1,41 +1,41 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/_RenderManager.hpp" #include "display/_RenderManager.hpp"
#include "display/BackBufferRenderTarget.hpp" #include "display/BackBufferRenderTarget.hpp"
#include "display/shader/SimpleTexturedShader.hpp" #include "display/shader/SimpleTexturedShader.hpp"
namespace Dawn { namespace Dawn {
class StandardRenderPipeline; class StandardRenderPipeline;
class RenderManager : public IRenderManager { class RenderManager : public IRenderManager {
private: private:
std::shared_ptr<StandardRenderPipeline> standardRenderPipeline; StandardRenderPipeline *standardRenderPipeline;
public: public:
BackBufferRenderTarget backBuffer; BackBufferRenderTarget backBuffer;
std::shared_ptr<SimpleTexturedShader> simpleShader; SimpleTexturedShader *simpleShader;
std::shared_ptr<UIShader> uiShader; UIShader *uiShader;
/** /**
* Construct a new RenderManager for a game instance. * Construct a new RenderManager for a game instance.
*/ */
RenderManager(DawnGame &game); RenderManager(DawnGame *game);
RenderTarget & getBackBuffer() override; RenderTarget * getBackBuffer() override;
RenderPipeline & getRenderPipeline() override; RenderPipeline * getRenderPipeline() override;
std::shared_ptr<Shader> getDefaultShader() override; Shader * getDefaultShader() override;
std::shared_ptr<UIShader> getUIShader() override; UIShader * getUIShader() override;
void setRenderFlags(renderflag_t renderFlags) override; void setRenderFlags(renderflag_t renderFlags) override;
void init() override; void init() override;
void update() override; void update() override;
/** /**
* Destroy a previously initialized RenderManager. * Destroy a previously initialized RenderManager.
*/ */
~RenderManager(); ~RenderManager();
}; };
} }

View File

@ -1,14 +1,14 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "StandardRenderPipeline.hpp" #include "StandardRenderPipeline.hpp"
#include "scene/components/Components.hpp" #include "scene/components/Components.hpp"
using namespace Dawn; using namespace Dawn;
StandardRenderPipeline::StandardRenderPipeline(RenderManager &renderManager) : StandardRenderPipeline::StandardRenderPipeline(RenderManager *renderManager) :
RenderPipeline(renderManager) RenderPipeline(renderManager)
{ {
} }

View File

@ -1,15 +1,15 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "display/RenderPipeline.hpp" #include "display/RenderPipeline.hpp"
namespace Dawn { namespace Dawn {
class StandardRenderPipeline : public RenderPipeline { class StandardRenderPipeline : public RenderPipeline {
public: public:
StandardRenderPipeline(RenderManager &renderManager); StandardRenderPipeline(RenderManager *renderManager);
}; };
} }

View File

@ -1,32 +1,37 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "display/_Texture.hpp" #include "display/_Texture.hpp"
#include "util/memory.hpp" #include "util/memory.hpp"
namespace Dawn { namespace Dawn {
typedef GLuint textureslot_t; typedef GLuint textureslot_t;
class Texture : public ITexture { class Texture : public ITexture {
private: private:
int32_t width = -1; int32_t width = -1;
int32_t height = -1; int32_t height = -1;
GLuint id = -1; GLuint id = -1;
public: public:
void bind(textureslot_t slot); int32_t getWidth() override;
int32_t getHeight() override;
int32_t getWidth() override; void setSize(int32_t width, int32_t height) override;
int32_t getHeight() override; void fill(struct Color) override;
void setSize(int32_t width, int32_t height) override; bool_t isReady() override;
void fill(struct Color) override; void buffer(struct Color pixels[]) override;
bool_t isReady() override;
void buffer(struct Color pixels[]) override; /**
* Binds the texture to the given slot (for use by the shaders).
~Texture(); *
}; * @param slot Slot to bind to.
*/
void bind(textureslot_t slot);
~Texture();
};
} }

View File

@ -1,136 +1,137 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/mesh/_Mesh.hpp" #include "display/mesh/_Mesh.hpp"
#include "dawnopengl.hpp" #include "dawnopengl.hpp"
#include "assert/assert.hpp"
/** Indice that references a specific vertice */
typedef int32_t meshindice_t; /** Indice that references a specific vertice */
typedef int32_t meshindice_t;
namespace Dawn {
enum MeshDrawMode { namespace Dawn {
MESH_DRAW_MODE_TRIANGLES = GL_TRIANGLES enum MeshDrawMode {
}; MESH_DRAW_MODE_TRIANGLES = GL_TRIANGLES
};
class Mesh {
private: class Mesh {
private:
protected:
/** Pointer to the vertex buffer on the GPU */ protected:
GLuint vertexBuffer = -1; /** Pointer to the vertex buffer on the GPU */
/** Pointer to the index buffer on the GPU */ GLuint vertexBuffer = -1;
GLuint indexBuffer = -1; /** Pointer to the index buffer on the GPU */
GLuint indexBuffer = -1;
/** How many vertices are in the mesh */
int32_t verticeCount = -1; /** How many vertices are in the mesh */
/** How many indices are in the mesh */ int32_t verticeCount = -1;
int32_t indiceCount = -1; /** How many indices are in the mesh */
int32_t indiceCount = -1;
public:
/** public:
* Create a new set of buffers for the mesh to use. /**
* * 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. * @param verticeCount How many Vertices will this buffer support.
*/ * @param indiceCount How many Indices will this buffer support.
void createBuffers( */
int32_t verticeCount, void createBuffers(
int32_t indiceCount int32_t verticeCount,
); int32_t indiceCount
);
/**
* Cleanup the buffers on a given mesh. This is useful if you intend to /**
* expand the count of vertices your mesh supports. * Cleanup the buffers on a given mesh. This is useful if you intend to
*/ * expand the count of vertices your mesh supports.
void disposeBuffers(); */
void disposeBuffers();
/**
* Write vertice positions to the mesh. /**
* * Write vertice positions to the mesh.
* @tparam N Size of the array, in terms of number of elements. *
* @param position Position, within the buffer, to write to. * @tparam N Size of the array, in terms of number of elements.
* @param vertices Array of positions to write. * @param position Position, within the buffer, to write to.
*/ * @param vertices Array of positions to write.
template<size_t N> */
void bufferPositions( template<size_t N>
int32_t position, void bufferPositions(
std::array<glm::vec3, N> positions int32_t position,
) { std::array<glm::vec3, N> positions
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer); ) {
glBufferSubData( glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
GL_ARRAY_BUFFER, glBufferSubData(
sizeof(glm::vec3) * position, GL_ARRAY_BUFFER,
sizeof(positions), sizeof(glm::vec3) * position,
(void *)positions.data() sizeof(positions),
); (void *)positions.data()
} );
}
/**
* Write vertice coordinates to the mesh. /**
* * Write vertice coordinates to the mesh.
* @tparam N Size of the array, in terms of number of elements. *
* @param position Position, within the buffer, to write to. * @tparam N Size of the array, in terms of number of elements.
* @param coordinates Array of coordinates to write. * @param position Position, within the buffer, to write to.
*/ * @param coordinates Array of coordinates to write.
template<size_t N> */
void bufferCoordinates( template<size_t N>
int32_t position, void bufferCoordinates(
std::array<glm::vec2, N> coordinates int32_t position,
) { std::array<glm::vec2, N> coordinates
auto offsetCoordinates = ( ) {
(sizeof(glm::vec3) * this->verticeCount) + auto offsetCoordinates = (
(sizeof(glm::vec2) * position) (sizeof(glm::vec3) * this->verticeCount) +
); (sizeof(glm::vec2) * position)
);
glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
glBufferSubData( glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer);
GL_ARRAY_BUFFER, glBufferSubData(
offsetCoordinates, GL_ARRAY_BUFFER,
sizeof(coordinates), offsetCoordinates,
(void *)coordinates.data() sizeof(coordinates),
); (void *)coordinates.data()
} );
}
/**
* Write indices to the mesh. /**
* * Write indices to the mesh.
* @tparam N Size of the array, in terms of number of elements. *
* @param position Position, within the buffer, to write to. * @tparam N Size of the array, in terms of number of elements.
* @param indices Array of indices to write. * @param position Position, within the buffer, to write to.
*/ * @param indices Array of indices to write.
template<size_t N> */
void bufferIndices( template<size_t N>
int32_t position, void bufferIndices(
std::array<meshindice_t, N> indices int32_t position,
) { std::array<meshindice_t, N> indices
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer); ) {
glBufferSubData( glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer);
GL_ELEMENT_ARRAY_BUFFER, glBufferSubData(
sizeof(meshindice_t) * position, GL_ELEMENT_ARRAY_BUFFER,
sizeof(indices), sizeof(meshindice_t) * position,
(void *)indices.data() sizeof(indices),
); (void *)indices.data()
} );
}
/**
* Draw a primitive. Primitives are drawn by their indices. /**
* * 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 drawMode Which drawing mode to use to draw the primitive.
* @param count Count of indices to draw. Use -1 to draw all. * @param start Start indice (index) to draw.
*/ * @param count Count of indices to draw. Use -1 to draw all.
void draw( */
enum MeshDrawMode drawMode, void draw(
int32_t start, enum MeshDrawMode drawMode,
int32_t count int32_t start,
); int32_t count
);
/**
* Cleanup a previously initiated mesh. /**
*/ * Cleanup a previously initiated mesh.
~Mesh(); */
}; ~Mesh();
};
} }

View File

@ -1,101 +1,101 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/shader/Shader.hpp" #include "display/shader/Shader.hpp"
#include "scene/components/Components.hpp" #include "scene/components/Components.hpp"
namespace Dawn { namespace Dawn {
class SimpleTexturedShader : public Shader { class SimpleTexturedShader : public Shader {
public: public:
shaderparameter_t paramProjection; shaderparameter_t paramProjection;
shaderparameter_t paramView; shaderparameter_t paramView;
shaderparameter_t paramModel; shaderparameter_t paramModel;
shaderparameter_t paramColor; shaderparameter_t paramColor;
shaderparameter_t paramTexture; shaderparameter_t paramTexture;
shaderparameter_t paramHasTexture; shaderparameter_t paramHasTexture;
std::map<shaderparameter_t, enum ShaderParameterType> std::map<shaderparameter_t, enum ShaderParameterType>
getParameters() override { getParameters() override {
std::map<shaderparameter_t, enum ShaderParameterType> ps; std::map<shaderparameter_t, enum ShaderParameterType> ps;
ps[this->paramColor] = SHADER_PARAMETER_TYPE_COLOR; ps[this->paramColor] = SHADER_PARAMETER_TYPE_COLOR;
ps[this->paramHasTexture] = SHADER_PARAMETER_TYPE_BOOLEAN; ps[this->paramHasTexture] = SHADER_PARAMETER_TYPE_BOOLEAN;
ps[this->paramTexture] = SHADER_PARAMETER_TYPE_TEXTURE; ps[this->paramTexture] = SHADER_PARAMETER_TYPE_TEXTURE;
return ps; return ps;
} }
void setDefaultParameters(Material &material) override { void setDefaultParameters(Material *material) override {
material.colorValues[this->paramColor] = COLOR_WHITE; material->colorValues[this->paramColor] = COLOR_WHITE;
} }
void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override { void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override {
this->setMatrix(this->paramProjection, proj); this->setMatrix(this->paramProjection, proj);
this->setMatrix(this->paramView, view); this->setMatrix(this->paramView, view);
} }
void setMeshParameters(glm::mat4 transform) override { void setMeshParameters(glm::mat4 transform) override {
this->setMatrix(this->paramModel, transform); this->setMatrix(this->paramModel, transform);
} }
void bindTexture( void bindTexture(
shaderparameter_t param, shaderparameter_t param,
Texture *texture Texture *texture
) override { ) override {
if(texture == nullptr) { if(texture == nullptr) {
this->setBoolean(this->paramHasTexture, false); this->setBoolean(this->paramHasTexture, false);
} else { } else {
this->setBoolean(this->paramHasTexture, true); this->setBoolean(this->paramHasTexture, true);
this->setTextureSlot(param, 0x00); this->setTextureSlot(param, 0x00);
texture->bind(0x00); texture->bind(0x00);
} }
} }
void compile() override { void compile() override {
this->compileShader( this->compileShader(
// Vertex Shader // Vertex Shader
"#version 330 core\n" "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n" "layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n" "layout (location = 1) in vec2 aTexCoord;\n"
"uniform mat4 u_Proj;\n" "uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n" "uniform mat4 u_View;\n"
"uniform mat4 u_Model;\n" "uniform mat4 u_Model;\n"
"out vec2 o_TextCoord;\n" "out vec2 o_TextCoord;\n"
"void main() {\n" "void main() {\n"
"gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n" "gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n"
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
"}", "}",
// Fragment Shader // Fragment Shader
"#version 330 core\n" "#version 330 core\n"
"out vec4 o_Color;\n" "out vec4 o_Color;\n"
"in vec2 o_TextCoord;\n" "in vec2 o_TextCoord;\n"
"uniform vec4 u_Color;\n" "uniform vec4 u_Color;\n"
"uniform sampler2D u_Text;\n" "uniform sampler2D u_Text;\n"
"uniform bool u_HasTexture;\n" "uniform bool u_HasTexture;\n"
"void main() {\n" "void main() {\n"
"if(u_HasTexture) {\n" "if(u_HasTexture) {\n"
"o_Color = texture(u_Text, o_TextCoord) * u_Color;\n" "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
"} else {\n" "} else {\n"
"o_Color = u_Color;" "o_Color = u_Color;"
"}\n" "}\n"
"}\n" "}\n"
); );
this->paramProjection = this->getParameterByName("u_Proj"); this->paramProjection = this->getParameterByName("u_Proj");
this->paramView = this->getParameterByName("u_View"); this->paramView = this->getParameterByName("u_View");
this->paramModel = this->getParameterByName("u_Model"); this->paramModel = this->getParameterByName("u_Model");
this->paramColor = this->getParameterByName("u_Color"); this->paramColor = this->getParameterByName("u_Color");
this->paramTexture = this->getParameterByName("u_Text"); this->paramTexture = this->getParameterByName("u_Text");
this->paramHasTexture = this->getParameterByName("u_HasTexture"); this->paramHasTexture = this->getParameterByName("u_HasTexture");
this->setBoolean(this->paramHasTexture, false); this->setBoolean(this->paramHasTexture, false);
} }
}; };
} }

View File

@ -1,119 +1,119 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include "display/shader/Shader.hpp" #include "display/shader/Shader.hpp"
#include "scene/components/Components.hpp" #include "scene/components/Components.hpp"
namespace Dawn { namespace Dawn {
class UIShader : public Shader { class UIShader : public Shader {
public: public:
shaderparameter_t paramProjection; shaderparameter_t paramProjection;
shaderparameter_t paramView; shaderparameter_t paramView;
shaderparameter_t paramModel; shaderparameter_t paramModel;
shaderparameter_t paramColor; shaderparameter_t paramColor;
shaderparameter_t paramTexture; shaderparameter_t paramTexture;
shaderparameter_t paramHasTexture; shaderparameter_t paramHasTexture;
std::map<shaderparameter_t, enum ShaderParameterType> std::map<shaderparameter_t, enum ShaderParameterType>
getParameters() override { getParameters() override {
std::map<shaderparameter_t, enum ShaderParameterType> ps; std::map<shaderparameter_t, enum ShaderParameterType> ps;
ps[this->paramColor] = SHADER_PARAMETER_TYPE_COLOR; ps[this->paramColor] = SHADER_PARAMETER_TYPE_COLOR;
ps[this->paramHasTexture] = SHADER_PARAMETER_TYPE_BOOLEAN; ps[this->paramHasTexture] = SHADER_PARAMETER_TYPE_BOOLEAN;
ps[this->paramTexture] = SHADER_PARAMETER_TYPE_TEXTURE; ps[this->paramTexture] = SHADER_PARAMETER_TYPE_TEXTURE;
return ps; return ps;
} }
void setDefaultParameters(Material &material) override { void setDefaultParameters(Material *material) override {
material.colorValues[this->paramColor] = COLOR_WHITE; material->colorValues[this->paramColor] = COLOR_WHITE;
} }
void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override { void setGlobalParameters(glm::mat4 proj, glm::mat4 view) override {
this->setMatrix(this->paramProjection, proj); this->setMatrix(this->paramProjection, proj);
this->setMatrix(this->paramView, view); this->setMatrix(this->paramView, view);
} }
void setMeshParameters(glm::mat4 transform) override { void setMeshParameters(glm::mat4 transform) override {
this->setMatrix(this->paramModel, transform); this->setMatrix(this->paramModel, transform);
} }
void bindTexture( void bindTexture(
shaderparameter_t param, shaderparameter_t param,
Texture *texture Texture *texture
) override { ) override {
if(texture == nullptr) { if(texture == nullptr) {
this->setBoolean(this->paramHasTexture, false); this->setBoolean(this->paramHasTexture, false);
} else { } else {
this->setBoolean(this->paramHasTexture, true); this->setBoolean(this->paramHasTexture, true);
this->setTextureSlot(param, 0x00); this->setTextureSlot(param, 0x00);
texture->bind(0x00); texture->bind(0x00);
} }
} }
void compile() override { void compile() override {
this->compileShader( this->compileShader(
// Vertex Shader // Vertex Shader
"#version 330 core\n" "#version 330 core\n"
"layout (location = 0) in vec3 aPos;\n" "layout (location = 0) in vec3 aPos;\n"
"layout (location = 1) in vec2 aTexCoord;\n" "layout (location = 1) in vec2 aTexCoord;\n"
"uniform mat4 u_Proj;\n" "uniform mat4 u_Proj;\n"
"uniform mat4 u_View;\n" "uniform mat4 u_View;\n"
"uniform mat4 u_Model;\n" "uniform mat4 u_Model;\n"
"out vec2 o_TextCoord;\n" "out vec2 o_TextCoord;\n"
"void main() {\n" "void main() {\n"
"gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n" "gl_Position = u_Proj * u_View * u_Model * vec4(aPos, 1.0);\n"
"o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n" "o_TextCoord = vec2(aTexCoord.x, aTexCoord.y);\n"
"}", "}",
// Fragment Shader // Fragment Shader
"#version 330 core\n" "#version 330 core\n"
"out vec4 o_Color;\n" "out vec4 o_Color;\n"
"in vec2 o_TextCoord;\n" "in vec2 o_TextCoord;\n"
"uniform vec4 u_Color;\n" "uniform vec4 u_Color;\n"
"uniform sampler2D u_Text;\n" "uniform sampler2D u_Text;\n"
"uniform bool u_HasTexture;\n" "uniform bool u_HasTexture;\n"
"void main() {\n" "void main() {\n"
"if(u_HasTexture) {\n" "if(u_HasTexture) {\n"
"o_Color = texture(u_Text, o_TextCoord) * u_Color;\n" "o_Color = texture(u_Text, o_TextCoord) * u_Color;\n"
"} else {\n" "} else {\n"
"o_Color = u_Color;" "o_Color = u_Color;"
"}\n" "}\n"
"}\n" "}\n"
); );
this->paramProjection = this->getParameterByName("u_Proj"); this->paramProjection = this->getParameterByName("u_Proj");
this->paramView = this->getParameterByName("u_View"); this->paramView = this->getParameterByName("u_View");
this->paramModel = this->getParameterByName("u_Model"); this->paramModel = this->getParameterByName("u_Model");
this->paramColor = this->getParameterByName("u_Color"); this->paramColor = this->getParameterByName("u_Color");
this->paramTexture = this->getParameterByName("u_Text"); this->paramTexture = this->getParameterByName("u_Text");
this->paramHasTexture = this->getParameterByName("u_HasTexture"); this->paramHasTexture = this->getParameterByName("u_HasTexture");
this->setBoolean(this->paramHasTexture, false); this->setBoolean(this->paramHasTexture, false);
} }
void setUICamera(glm::mat4 view, glm::mat4 projection) { void setUICamera(glm::mat4 view, glm::mat4 projection) {
this->setMatrix(this->paramView, view); this->setMatrix(this->paramView, view);
this->setMatrix(this->paramProjection, projection); this->setMatrix(this->paramProjection, projection);
} }
void setUIModel(glm::mat4 model) { void setUIModel(glm::mat4 model) {
this->setMatrix(this->paramModel, model); this->setMatrix(this->paramModel, model);
} }
void setUITexture(Texture *texture) { void setUITexture(Texture *texture) {
this->bindTexture(this->paramTexture, texture); this->bindTexture(this->paramTexture, texture);
} }
void setUIColor(struct Color color) { void setUIColor(struct Color color) {
this->setColor(this->paramColor, color); this->setColor(this->paramColor, color);
} }
}; };
} }

View File

@ -10,13 +10,13 @@
using namespace Dawn; using namespace Dawn;
std::shared_ptr<TrueTypeAsset> assetFont; TrueTypeAsset *assetFont;
std::shared_ptr<TextureAsset> assetTexture; TextureAsset *assetTexture;
DawnGame::DawnGame(DawnHost &host) : DawnGame::DawnGame(DawnHost *host) :
host(host), host(host),
renderManager(*this), renderManager(this),
inputManager(*this) inputManager(this)
{ {
} }
@ -24,11 +24,11 @@ int32_t DawnGame::init() {
this->assetManager.init(); this->assetManager.init();
this->renderManager.init(); this->renderManager.init();
this->scene = std::make_shared<Scene>(*this); this->scene = new Scene(this);
auto cameraObject = this->scene->createSceneItem(); auto cameraObject = this->scene->createSceneItem();
auto camera = cameraObject->addComponent<Camera>(); auto camera = cameraObject->addComponent<Camera>();
camera->transform.lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0)); camera->transform->lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0));
auto canvas = UICanvas::createCanvas(this->scene); auto canvas = UICanvas::createCanvas(this->scene);
@ -39,7 +39,7 @@ int32_t DawnGame::init() {
} }
auto textbox = canvas->addElement<VisualNovelTextbox>(); auto textbox = canvas->addElement<VisualNovelTextbox>();
textbox->setBorder(assetTexture->texture.get(), glm::vec2(16, 16)); textbox->setBorder(&assetTexture->texture, glm::vec2(16, 16));
textbox->setFont(&assetFont->font); textbox->setFont(&assetFont->font);
textbox->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus leo odio, egestas nec imperdiet ac, placerat eget quam. Nam tellus justo, aliquam sed porta quis, ullamcorper in libero. Proin auctor eget elit nec rutrum. Vestibulum tincidunt sem vel nisi sagittis, sed imperdiet eros aliquet. Fusce a ultrices augue, at auctor lacus. Sed lobortis, ante vitae vehicula egestas, lorem turpis cursus dui, sit amet egestas mauris ligula non ipsum. Pellentesque scelerisque posuere lorem sit amet tempor. Praesent ac hendrerit mi. Nulla mollis diam vitae vestibulum aliquam. Nullam metus justo, viverra sed risus eu, tincidunt sodales lacus. Quisque efficitur accumsan posuere. Aliquam posuere volutpat diam quis lacinia. Nullam blandit nulla vestibulum mi placerat varius. Proin egestas lacus nec pellentesque iaculis. Vestibulum ex metus, congue in eleifend et, scelerisque a nulla. Pellentesque cursus lectus sed arcu efficitur tincidunt. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla a felis non velit fermentum ullamcorper.", 40); textbox->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus leo odio, egestas nec imperdiet ac, placerat eget quam. Nam tellus justo, aliquam sed porta quis, ullamcorper in libero. Proin auctor eget elit nec rutrum. Vestibulum tincidunt sem vel nisi sagittis, sed imperdiet eros aliquet. Fusce a ultrices augue, at auctor lacus. Sed lobortis, ante vitae vehicula egestas, lorem turpis cursus dui, sit amet egestas mauris ligula non ipsum. Pellentesque scelerisque posuere lorem sit amet tempor. Praesent ac hendrerit mi. Nulla mollis diam vitae vestibulum aliquam. Nullam metus justo, viverra sed risus eu, tincidunt sodales lacus. Quisque efficitur accumsan posuere. Aliquam posuere volutpat diam quis lacinia. Nullam blandit nulla vestibulum mi placerat varius. Proin egestas lacus nec pellentesque iaculis. Vestibulum ex metus, congue in eleifend et, scelerisque a nulla. Pellentesque cursus lectus sed arcu efficitur tincidunt. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla a felis non velit fermentum ullamcorper.", 40);
textbox->setTransform( textbox->setTransform(

View File

@ -10,13 +10,13 @@
namespace Dawn { namespace Dawn {
class DawnGame : public IDawnGame { class DawnGame : public IDawnGame {
public: public:
DawnHost &host; DawnHost *host;
RenderManager renderManager; RenderManager renderManager;
AssetManager assetManager; AssetManager assetManager;
InputManager inputManager; InputManager inputManager;
TimeManager timeManager; TimeManager timeManager;
DawnGame(DawnHost &host); DawnGame(DawnHost *host);
int32_t init() override; int32_t init() override;
int32_t update(float_t delta) override; int32_t update(float_t delta) override;
}; };

View File

@ -1,42 +1,45 @@
// Copyright (c) 2022 Dominic Masters // Copyright (c) 2022 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#include "DawnHostWin32.hpp" #include "DawnHostWin32.hpp"
using namespace Dawn; using namespace Dawn;
int32_t main(int32_t argc, char **args) { int32_t main(int32_t argc, char **args) {
int32_t result; int32_t result;
// Create the host // Create the host
auto host = std::make_shared<DawnHost>(); auto host = new DawnHost();
auto game = std::make_shared<DawnGame>(*host); auto game = new DawnGame(host);
// Initialize the host and error check // Initialize the host and error check
result = host->init(*game); result = host->init(game);
switch(result) { switch(result) {
case DAWN_HOST_INIT_RESULT_SUCCESS: case DAWN_HOST_INIT_RESULT_SUCCESS:
break; break;
default: default:
return result; return result;
} }
// Request the main loop to start running. // Request the main loop to start running.
result = host->start(*game); result = host->start(game);
switch(result) { switch(result) {
case DAWN_HOST_START_RESULT_SUCCESS: case DAWN_HOST_START_RESULT_SUCCESS:
break; break;
case DAWN_HOST_START_RESULT_EXIT_SUCCESS: case DAWN_HOST_START_RESULT_EXIT_SUCCESS:
break; break;
default: default:
return result; return result;
} }
// Main loop finished without errors, cleanup // Main loop finished without errors, cleanup
host->unload(*game); host->unload(game);
// Success delete game;
return 0; delete host;
// Success
return 0;
} }