Part one - removed references and smart pointers
This commit is contained in:
@ -17,6 +17,7 @@ target_include_directories(${DAWN_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(assert)
|
||||
add_subdirectory(asset)
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(input)
|
||||
|
@ -3,7 +3,7 @@
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
target_sources(${PROJECT_NAME}
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
assert.cpp
|
||||
)
|
@ -27,15 +27,11 @@
|
||||
}
|
||||
|
||||
void assertNotNull(const void *pointer) {
|
||||
assertTrue(pointer != NULL);
|
||||
}
|
||||
|
||||
void assertNotNullptr(const void *ptr) {
|
||||
assertTRue(ptr != nullptr);
|
||||
assertTrue(pointer != nullptr && pointer != NULL);
|
||||
}
|
||||
|
||||
void assertNull(const void *pointer) {
|
||||
assertTrue(pointer == NULL);
|
||||
assertTrue(pointer == NULL || pointer == nullptr);
|
||||
}
|
||||
|
||||
void assertDeprecated() {
|
||||
|
@ -13,11 +13,6 @@
|
||||
#if ASSERTS_ENABLED == 0
|
||||
|
||||
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
|
||||
|
||||
@ -45,13 +40,6 @@ static inline void assertDeprecated() {}
|
||||
*/
|
||||
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.
|
||||
* @param pointer Pointer to assert is nullptr.
|
||||
@ -66,9 +54,5 @@ static inline void assertDeprecated() {}
|
||||
#else
|
||||
|
||||
#define assertTrue assert
|
||||
#define assertFalse(x) assertTrue(x == 0)
|
||||
#define assertNotNull(x) assert(x != NULL)
|
||||
#define assertUnreachable() assert(false)
|
||||
#define assertDeprecated assertUnreachable
|
||||
|
||||
#endif
|
@ -1,18 +1,20 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Asset::Asset(AssetManager &assetManager, std::string name) :
|
||||
assetManager(assetManager)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
Asset::~Asset() {
|
||||
this->loaded = false;
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Asset::Asset(AssetManager *assetManager, std::string name) {
|
||||
assertTrue(name.size() > 0);
|
||||
assertNotNull(assetManager);
|
||||
|
||||
this->assetManager = assetManager;
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
Asset::~Asset() {
|
||||
this->loaded = false;
|
||||
}
|
@ -1,46 +1,47 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager;
|
||||
|
||||
class Asset {
|
||||
public:
|
||||
AssetManager &assetManager;
|
||||
std::string name;
|
||||
uint8_t state = 0x00;
|
||||
bool loaded = false;
|
||||
|
||||
/**
|
||||
* Create an abstract Asset object.
|
||||
*
|
||||
* @param assetManager Asset manager that this asset belongs to.
|
||||
* @param name Name of the asset.
|
||||
*/
|
||||
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
|
||||
* the loaded is also false.
|
||||
*/
|
||||
virtual void updateSync() = 0;
|
||||
|
||||
/**
|
||||
* Virtual function called by the asset manager asynchronously every tick.
|
||||
* This will only trigger if blocks are false and the loaded state is also
|
||||
* false.
|
||||
*/
|
||||
virtual void updateAsync() = 0;
|
||||
|
||||
/**
|
||||
* Dispose the asset item.
|
||||
*/
|
||||
virtual ~Asset();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager;
|
||||
|
||||
class Asset {
|
||||
public:
|
||||
AssetManager *assetManager;
|
||||
std::string name;
|
||||
uint8_t state = 0x00;
|
||||
bool loaded = false;
|
||||
|
||||
/**
|
||||
* Create an abstract Asset object.
|
||||
*
|
||||
* @param assetManager Asset manager that this asset belongs to.
|
||||
* @param name Name of the asset.
|
||||
*/
|
||||
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
|
||||
* the loaded is also false.
|
||||
*/
|
||||
virtual void updateSync() = 0;
|
||||
|
||||
/**
|
||||
* Virtual function called by the asset manager asynchronously every tick.
|
||||
* This will only trigger if blocks are false and the loaded state is also
|
||||
* false.
|
||||
*/
|
||||
virtual void updateAsync() = 0;
|
||||
|
||||
/**
|
||||
* Dispose the asset item.
|
||||
*/
|
||||
virtual ~Asset();
|
||||
};
|
||||
}
|
@ -1,87 +1,99 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) {
|
||||
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");
|
||||
if(this->handle == NULL || this->handle == nullptr) {
|
||||
throw "Failed to open file handle for " + this->fileName;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
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);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::end() {
|
||||
return fseek(this->handle, 0, SEEK_END);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
return fseek(this->handle, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::rewind() {
|
||||
return fseek(this->handle, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
return ftell(this->handle);
|
||||
}
|
||||
|
||||
size_t AssetLoader::loadRaw(uint8_t **buffer) {
|
||||
size_t length, read;
|
||||
|
||||
// Open a buffer.
|
||||
this->open();
|
||||
|
||||
// Read the count of bytes in the file
|
||||
this->end();
|
||||
length = this->getPosition();
|
||||
|
||||
// Are we only reading the size?
|
||||
if(buffer == nullptr) {
|
||||
this->close();
|
||||
return length;
|
||||
}
|
||||
|
||||
// Reset to start
|
||||
this->rewind();
|
||||
|
||||
// Read the string then close the file handle.
|
||||
*buffer = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * length));
|
||||
read = this->read(*buffer, length);
|
||||
this->close();
|
||||
|
||||
// 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;
|
||||
}
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) {
|
||||
assertTrue(fileName.size() > 0);
|
||||
|
||||
this->fileName = fileName;
|
||||
this->handle = nullptr;
|
||||
}
|
||||
|
||||
void AssetLoader::open() {
|
||||
assertNull(this->handle);
|
||||
std::string pathFull = DAWN_ASSET_BUILD_PREFIX + this->fileName;
|
||||
this->handle = fopen(pathFull.c_str(), "rb");
|
||||
assertNotNull(this->handle);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
assertNotNull(this->handle);
|
||||
int32_t ret = fclose(this->handle);
|
||||
this->handle = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t AssetLoader::read(uint8_t *buffer, size_t size) {
|
||||
assertNotNull(buffer);
|
||||
assertTrue(size > 0);
|
||||
assertNotNull(this->handle);
|
||||
return fread(buffer, 1, size, this->handle);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::end() {
|
||||
assertNotNull(this->handle);
|
||||
return fseek(this->handle, 0, SEEK_END);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
assertTrue(n > 0);
|
||||
assertNotNull(this->handle);
|
||||
return fseek(this->handle, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
int32_t AssetLoader::rewind() {
|
||||
assertNotNull(this->handle);
|
||||
return fseek(this->handle, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
assertNotNull(this->handle);
|
||||
return ftell(this->handle);
|
||||
}
|
||||
|
||||
size_t AssetLoader::loadRaw(uint8_t **buffer) {
|
||||
size_t length, read;
|
||||
|
||||
assertNotNull(buffer);
|
||||
|
||||
// Open a buffer.
|
||||
this->open();
|
||||
|
||||
// Read the count of bytes in the file
|
||||
this->end();
|
||||
length = this->getPosition();
|
||||
|
||||
// Are we only reading the size?
|
||||
if(buffer == nullptr) {
|
||||
this->close();
|
||||
return length;
|
||||
}
|
||||
|
||||
// Reset to start
|
||||
this->rewind();
|
||||
|
||||
// Read the string then close the file handle.
|
||||
*buffer = static_cast<uint8_t *>(malloc(sizeof(uint8_t) * length));
|
||||
read = this->read(*buffer, length);
|
||||
this->close();
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
@ -1,126 +1,130 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader {
|
||||
private:
|
||||
std::string fileName;
|
||||
FILE *handle;
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
AssetLoader(std::string fileName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
void open();
|
||||
|
||||
/**
|
||||
* Closes the previously ppened asset.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t close();
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
* @param buffer Pointer to a ubyte array to buffer data into.
|
||||
* @param size Length of the data buffer (How many bytes to read).
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Skip to the end of the buffer, useful to find the length of the buffer.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t end();
|
||||
|
||||
/**
|
||||
* Method to skip n bytes in the buffer
|
||||
* @param n Count of bytes to skip.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
size_t skip(size_t n);
|
||||
|
||||
/**
|
||||
* Rewinds to the start of the asset buffer.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
int32_t rewind();
|
||||
|
||||
|
||||
/**
|
||||
* Retreive the current byte position within the asset that the head is
|
||||
* at.
|
||||
* @return Position (in bytes) that the current seek is at.
|
||||
*/
|
||||
size_t getPosition();
|
||||
|
||||
/**
|
||||
* Loads the entire file into a raw buffer.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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)) {
|
||||
uint8_t buffer[1024];
|
||||
size_t read, length;
|
||||
int32_t i;
|
||||
bool result;
|
||||
|
||||
// Open the buffer.
|
||||
this->open();
|
||||
|
||||
// Reset length size
|
||||
length = 0;
|
||||
|
||||
// Buffer from input
|
||||
while((read = this->read(buffer, 1024)) != 0) {
|
||||
for(i = 0; i < read; i++) {
|
||||
result = ((*instance).*(callback))(buffer[i]);
|
||||
if(!result) {
|
||||
length += i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!result) break;
|
||||
length += read;
|
||||
}
|
||||
|
||||
// Close the buffer
|
||||
this->close();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the asset loader.
|
||||
*/
|
||||
virtual ~AssetLoader();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader {
|
||||
private:
|
||||
std::string fileName;
|
||||
FILE *handle;
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
AssetLoader(std::string fileName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
void open();
|
||||
|
||||
/**
|
||||
* Closes the previously ppened asset.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t close();
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
* @param buffer Pointer to a ubyte array to buffer data into.
|
||||
* @param size Length of the data buffer (How many bytes to read).
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
|
||||
/**
|
||||
* Skip to the end of the buffer, useful to find the length of the buffer.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t end();
|
||||
|
||||
/**
|
||||
* Method to skip n bytes in the buffer
|
||||
* @param n Count of bytes to skip.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
size_t skip(size_t n);
|
||||
|
||||
/**
|
||||
* Rewinds to the start of the asset buffer.
|
||||
* @return 0 if successful, otherwise unsuccessful.
|
||||
*/
|
||||
int32_t rewind();
|
||||
|
||||
|
||||
/**
|
||||
* Retreive the current byte position within the asset that the head is
|
||||
* at.
|
||||
* @return Position (in bytes) that the current seek is at.
|
||||
*/
|
||||
size_t getPosition();
|
||||
|
||||
/**
|
||||
* Loads the entire file into a raw buffer.
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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)) {
|
||||
uint8_t buffer[1024];
|
||||
size_t read, length;
|
||||
int32_t i;
|
||||
bool result;
|
||||
|
||||
assertNotNull(instance);
|
||||
assertNotNull(callback);
|
||||
|
||||
// Open the buffer.
|
||||
this->open();
|
||||
|
||||
// Reset length size
|
||||
length = 0;
|
||||
|
||||
// Buffer from input
|
||||
while((read = this->read(buffer, 1024)) != 0) {
|
||||
for(i = 0; i < read; i++) {
|
||||
result = ((*instance).*(callback))(buffer[i]);
|
||||
if(!result) {
|
||||
length += i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!result) break;
|
||||
length += read;
|
||||
}
|
||||
|
||||
// Close the buffer
|
||||
this->close();
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cleanup the asset loader.
|
||||
*/
|
||||
virtual ~AssetLoader();
|
||||
};
|
||||
}
|
@ -1,37 +1,52 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
#if !defined(DAWN_ASSET_BUILD_PREFIX)
|
||||
#error Asset Prefix has not been defined.
|
||||
#endif
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void AssetManager::init() {
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::update() {
|
||||
auto it = this->assetsNotLoaded.begin();
|
||||
while(it != this->assetsNotLoaded.end()) {
|
||||
auto asset = it->second;
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
asset->updateSync();
|
||||
asset->updateAsync();
|
||||
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetManager.hpp"
|
||||
|
||||
#if !defined(DAWN_ASSET_BUILD_PREFIX)
|
||||
#error Asset Prefix has not been defined.
|
||||
#endif
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void AssetManager::init() {
|
||||
|
||||
}
|
||||
|
||||
void AssetManager::update() {
|
||||
auto it = this->assetsNotLoaded.begin();
|
||||
while(it != this->assetsNotLoaded.end()) {
|
||||
auto asset = it->second;
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
continue;
|
||||
}
|
||||
|
||||
asset->updateSync();
|
||||
asset->updateAsync();
|
||||
|
||||
if(asset->loaded) {
|
||||
it = this->assetsNotLoaded.erase(it);
|
||||
this->assets[asset->name] = asset;
|
||||
continue;
|
||||
}
|
||||
|
||||
++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;
|
||||
}
|
||||
}
|
@ -1,38 +1,42 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "asset/Asset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager {
|
||||
private:
|
||||
/** List of pointers to assets, mapped by their asset key. */
|
||||
std::map<std::string, std::shared_ptr<Asset>> assets;
|
||||
std::map<std::string, std::shared_ptr<Asset>> assetsNotLoaded;
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Creates and queue an asset to load.
|
||||
*
|
||||
* @param name Name of the asset to load.
|
||||
* @return The asset element to be loaded.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> load(std::string name) {
|
||||
auto existing = this->assets.find(name);
|
||||
if(existing != this->assets.end()) {
|
||||
return std::dynamic_pointer_cast<T>(existing->second);
|
||||
}
|
||||
auto asset = std::make_shared<T>(*this, name);
|
||||
this->assets[name] = asset;
|
||||
this->assetsNotLoaded[name] = asset;
|
||||
return asset;
|
||||
}
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "Asset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetManager {
|
||||
private:
|
||||
/** List of pointers to assets, mapped by their asset key. */
|
||||
std::map<std::string, Asset*> assets;
|
||||
std::map<std::string, Asset*> assetsNotLoaded;
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Creates and queue an asset to load.
|
||||
*
|
||||
* @param name Name of the asset to load.
|
||||
* @return The asset element to be loaded.
|
||||
*/
|
||||
template<class T>
|
||||
T * load(std::string name) {
|
||||
assertTrue(name.size() > 0);
|
||||
|
||||
auto existing = this->assets.find(name);
|
||||
if(existing != this->assets.end()) {
|
||||
return (T*)existing->second;
|
||||
}
|
||||
auto asset = new T(this, name);
|
||||
this->assets[name] = asset;
|
||||
this->assetsNotLoaded[name] = asset;
|
||||
return asset;
|
||||
}
|
||||
|
||||
~AssetManager();
|
||||
};
|
||||
}
|
@ -1,64 +1,64 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TextureAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TextureAsset::TextureAsset(AssetManager &assetManager, std::string name) :
|
||||
Asset(assetManager, name),
|
||||
loader(name + ".texture")
|
||||
{
|
||||
this->texture = std::make_shared<Texture>();
|
||||
}
|
||||
|
||||
void TextureAsset::updateSync() {
|
||||
if(
|
||||
this->state != 0x03
|
||||
) return;
|
||||
|
||||
this->state = 0x04;
|
||||
this->texture->setSize(this->width, this->height);
|
||||
this->texture->buffer(this->colors);
|
||||
this->state = 0x05;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TextureAsset::updateAsync() {
|
||||
if(this->state != 0x00) return;
|
||||
this->state = 0x01;
|
||||
this->loader.loadRaw(&this->buffer);
|
||||
this->state = 0x02;
|
||||
|
||||
// Parse header data.
|
||||
char integer[32];
|
||||
size_t j = 0, i = 0;
|
||||
while(true) {
|
||||
auto c = this->buffer[i++];
|
||||
if(c == '|') {
|
||||
integer[j] = '\0';
|
||||
if(this->width == -1) {
|
||||
this->width = atoi(integer);
|
||||
if(this->width <= 0) throw "Invalid width";
|
||||
j = 0;
|
||||
continue;
|
||||
} else {
|
||||
this->height = atoi(integer);
|
||||
if(this->height <= 0) throw "Invalid height";
|
||||
break;
|
||||
}
|
||||
}
|
||||
integer[j++] = c;
|
||||
}
|
||||
|
||||
this->colors = (struct Color *)((void *)(this->buffer + i));
|
||||
this->state = 0x03;
|
||||
}
|
||||
|
||||
TextureAsset::~TextureAsset() {
|
||||
if(this->buffer != nullptr) {
|
||||
memoryFree(this->buffer);
|
||||
}
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TextureAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TextureAsset::TextureAsset(AssetManager *assetManager, std::string name) :
|
||||
Asset(assetManager, name),
|
||||
loader(name + ".texture"),
|
||||
texture()
|
||||
{
|
||||
}
|
||||
|
||||
void TextureAsset::updateSync() {
|
||||
if(
|
||||
this->state != 0x03
|
||||
) return;
|
||||
|
||||
this->state = 0x04;
|
||||
this->texture.setSize(this->width, this->height);
|
||||
this->texture.buffer(this->colors);
|
||||
this->state = 0x05;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TextureAsset::updateAsync() {
|
||||
if(this->state != 0x00) return;
|
||||
this->state = 0x01;
|
||||
this->loader.loadRaw(&this->buffer);
|
||||
this->state = 0x02;
|
||||
|
||||
// Parse header data.
|
||||
char integer[32];
|
||||
size_t j = 0, i = 0;
|
||||
while(true) {
|
||||
auto c = this->buffer[i++];
|
||||
if(c == '|') {
|
||||
integer[j] = '\0';
|
||||
if(this->width == -1) {
|
||||
this->width = atoi(integer);
|
||||
assertTrue(this->width > 0);
|
||||
j = 0;
|
||||
continue;
|
||||
} else {
|
||||
this->height = atoi(integer);
|
||||
assertTrue(this->height > 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
integer[j++] = c;
|
||||
}
|
||||
|
||||
this->colors = (struct Color *)((void *)(this->buffer + i));
|
||||
this->state = 0x03;
|
||||
}
|
||||
|
||||
TextureAsset::~TextureAsset() {
|
||||
if(this->buffer != nullptr) {
|
||||
memoryFree(this->buffer);
|
||||
}
|
||||
}
|
@ -1,29 +1,40 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TextureAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
int32_t width = -1, height = -1;
|
||||
struct Color *colors;
|
||||
|
||||
public:
|
||||
std::shared_ptr<Texture> texture;
|
||||
|
||||
TextureAsset(AssetManager &assetManager, std::string name);
|
||||
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
~TextureAsset();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TextureAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
int32_t width = -1, height = -1;
|
||||
struct Color *colors;
|
||||
|
||||
public:
|
||||
Texture texture;
|
||||
|
||||
/**
|
||||
* Constructs a texture asset loader. You should instead use the parent
|
||||
* asset managers' abstracted load method
|
||||
*
|
||||
* @param assetManager Asset manager this asset belongs to.
|
||||
* @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();
|
||||
};
|
||||
}
|
@ -1,76 +1,86 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TrueTypeAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TrueTypeAsset::TrueTypeAsset(AssetManager &assMan, std::string name) :
|
||||
Asset(assMan, name),
|
||||
loader(name + ".truetype")
|
||||
{
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateSync() {
|
||||
if(this->state != 0x04) return;
|
||||
this->font.texture.setSize(this->width, this->height);
|
||||
this->font.texture.buffer(this->pixels);
|
||||
auto i = this->pixels;
|
||||
memoryCopy(
|
||||
this->characterData,
|
||||
this->font.characterData,
|
||||
sizeof(truetypechar_t) * TRUETYPE_NUM_CHARS
|
||||
);
|
||||
this->state = 0x05;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateAsync() {
|
||||
int32_t fontSize;
|
||||
size_t i, j;
|
||||
char intBuffer[32];
|
||||
char c;
|
||||
|
||||
if(this->state != 0x00) return;
|
||||
|
||||
this->state = 0x01;
|
||||
this->loader.loadRaw(&this->buffer);
|
||||
this->state = 0x02;
|
||||
|
||||
// Parse header data.
|
||||
i = j = 0;
|
||||
width = -1, height = -1, fontSize = -1;
|
||||
while(true) {
|
||||
c = this->buffer[i++];
|
||||
if(c == '|') {
|
||||
intBuffer[j] = '\0';
|
||||
if(width == -1) {
|
||||
this->width = atoi(intBuffer);
|
||||
j = 0;
|
||||
continue;
|
||||
} else if(height == -1) {
|
||||
this->height = atoi(intBuffer);
|
||||
j = 0;
|
||||
continue;
|
||||
} else {
|
||||
fontSize = atoi(intBuffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
intBuffer[j++] = c;
|
||||
}
|
||||
|
||||
this->state = 0x03;
|
||||
this->font.fontSize = fontSize;
|
||||
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() {
|
||||
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "TrueTypeAsset.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
TrueTypeAsset::TrueTypeAsset(AssetManager *assMan, std::string name) :
|
||||
Asset(assMan, name),
|
||||
loader(name + ".truetype")
|
||||
{
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateSync() {
|
||||
if(this->state != 0x04) return;
|
||||
this->font.texture.setSize(this->width, this->height);
|
||||
this->font.texture.buffer(this->pixels);
|
||||
auto i = this->pixels;
|
||||
memoryCopy(
|
||||
this->characterData,
|
||||
this->font.characterData,
|
||||
sizeof(truetypechar_t) * TRUETYPE_NUM_CHARS
|
||||
);
|
||||
|
||||
memoryFree(this->buffer);
|
||||
this->buffer = nullptr;
|
||||
|
||||
this->state = 0x05;
|
||||
this->loaded = true;
|
||||
}
|
||||
|
||||
void TrueTypeAsset::updateAsync() {
|
||||
int32_t fontSize;
|
||||
size_t i, j;
|
||||
char intBuffer[32];
|
||||
char c;
|
||||
|
||||
if(this->state != 0x00) return;
|
||||
|
||||
this->state = 0x01;
|
||||
this->loader.loadRaw(&this->buffer);
|
||||
this->state = 0x02;
|
||||
|
||||
// Parse header data.
|
||||
i = j = 0;
|
||||
width = -1, height = -1, fontSize = -1;
|
||||
while(true) {
|
||||
c = this->buffer[i++];
|
||||
if(c == '|') {
|
||||
intBuffer[j] = '\0';
|
||||
if(width == -1) {
|
||||
this->width = atoi(intBuffer);
|
||||
assertTrue(this->width > 0);
|
||||
j = 0;
|
||||
continue;
|
||||
} else if(height == -1) {
|
||||
this->height = atoi(intBuffer);
|
||||
assertTrue(this->height > 0);
|
||||
j = 0;
|
||||
continue;
|
||||
} else {
|
||||
fontSize = atoi(intBuffer);
|
||||
assertTrue(fontSize > 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
intBuffer[j++] = c;
|
||||
}
|
||||
|
||||
this->state = 0x03;
|
||||
this->font.fontSize = fontSize;
|
||||
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;
|
||||
}
|
||||
}
|
@ -1,30 +1,40 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "display/font/TrueTypeFont.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TrueTypeAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
truetypechar_t *characterData = nullptr;
|
||||
struct Color *pixels = nullptr;
|
||||
int32_t width, height;
|
||||
|
||||
public:
|
||||
TrueTypeFont font;
|
||||
|
||||
TrueTypeAsset(AssetManager &assMan, std::string name);
|
||||
|
||||
void updateSync() override;
|
||||
void updateAsync() override;
|
||||
|
||||
~TrueTypeAsset();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "display/font/TrueTypeFont.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TrueTypeAsset : public Asset {
|
||||
protected:
|
||||
AssetLoader loader;
|
||||
uint8_t *buffer = nullptr;
|
||||
truetypechar_t *characterData = nullptr;
|
||||
struct Color *pixels = nullptr;
|
||||
int32_t width, height;
|
||||
|
||||
public:
|
||||
TrueTypeFont font;
|
||||
|
||||
/**
|
||||
* Constructs a new True Type Asset. As with all other assets you should
|
||||
* instead use the AssetManaager.load method.
|
||||
*
|
||||
* @param assMan Asset manager that this asset belongs to.
|
||||
* @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();
|
||||
};
|
||||
}
|
@ -1,140 +1,141 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RenderPipeline.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderManager &renderManager) :
|
||||
renderManager(renderManager)
|
||||
{
|
||||
}
|
||||
|
||||
void RenderPipeline::init() {
|
||||
|
||||
}
|
||||
|
||||
void RenderPipeline::render() {
|
||||
this->renderScene(*this->renderManager.game.scene);
|
||||
}
|
||||
|
||||
void RenderPipeline::renderScene(Scene &scene) {
|
||||
RenderTarget &backBuffer = this->renderManager.getBackBuffer();
|
||||
auto cameras = scene.findComponents<Camera>();
|
||||
std::shared_ptr<Camera> backBufferCamera = nullptr;
|
||||
|
||||
// First, render all non-backbuffer cameras.
|
||||
auto it = cameras.begin();
|
||||
while(it != cameras.end()) {
|
||||
RenderTarget &cameraTarget = (*it)->getRenderTarget();
|
||||
|
||||
// Leave the backbuffer camera(s) to last, so we skip them.
|
||||
if(&cameraTarget == &backBuffer) {
|
||||
backBufferCamera = *it;
|
||||
} else {
|
||||
this->renderSceneCamera(scene, **it);
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
// Now render the backbuffer camera.
|
||||
if(backBufferCamera == nullptr) return;
|
||||
this->renderSceneCamera(scene, *backBufferCamera);
|
||||
|
||||
// Now we try and render UI components
|
||||
auto uiCanvasList = scene.findComponents<UICanvas>();
|
||||
auto itCanvas = uiCanvasList.begin();
|
||||
while(itCanvas != uiCanvasList.end()) {
|
||||
this->renderUI(scene, *backBufferCamera, **itCanvas);
|
||||
++itCanvas;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) {
|
||||
RenderTarget &renderTarget = camera.getRenderTarget();
|
||||
renderTarget.bind();
|
||||
renderTarget.clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
this->renderManager.setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND
|
||||
);
|
||||
|
||||
auto meshes = scene.findComponents<MeshRenderer>();
|
||||
auto it = meshes.begin();
|
||||
while(it != meshes.end()) {
|
||||
auto mesh = *it;
|
||||
auto material = mesh->item.getComponent<Material>();
|
||||
|
||||
// TODO: fallback material?
|
||||
if(material == nullptr) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto shader = material->getShader();
|
||||
shader->bind();
|
||||
shader->setGlobalParameters(camera.projection, camera.transform.getWorldTransform());
|
||||
shader->setMeshParameters(mesh->item.transform.getWorldTransform());
|
||||
material->setShaderParameters();
|
||||
|
||||
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::renderUI(
|
||||
Scene &scene,
|
||||
Camera &camera,
|
||||
UICanvas &canvas
|
||||
) {
|
||||
// Get the
|
||||
RenderTarget *renderTarget;
|
||||
|
||||
glm::mat4 transform;
|
||||
glm::mat4 projection;
|
||||
switch(canvas.drawType) {
|
||||
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
||||
transform = glm::mat4(1.0f);
|
||||
projection = glm::ortho(0.0f, canvas.getWidth(), canvas.getHeight(), 0.0f);
|
||||
renderTarget = &camera.getRenderTarget();
|
||||
break;
|
||||
default:
|
||||
throw "UI Draw modes are not yet supported.";
|
||||
}
|
||||
|
||||
// Clear / Bind / Update the render target.
|
||||
renderTarget->bind();
|
||||
renderTarget->clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
this->renderManager.setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND |
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
|
||||
);
|
||||
|
||||
// Prepare the UI Shader
|
||||
auto shader = this->renderManager.getUIShader();
|
||||
shader->bind();
|
||||
shader->setUICamera(transform, projection);
|
||||
|
||||
// Render the children
|
||||
glm::mat4 rootMatrix = canvas.transform.getWorldTransform();
|
||||
auto it = canvas.children.begin();
|
||||
while(it != canvas.children.end()) {
|
||||
(*it)->draw(*shader, rootMatrix);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "RenderPipeline.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
RenderPipeline::RenderPipeline(RenderManager *renderManager) {
|
||||
assertNotNull(renderManager);
|
||||
this->renderManager = renderManager;
|
||||
}
|
||||
|
||||
void RenderPipeline::init() {
|
||||
|
||||
}
|
||||
|
||||
void RenderPipeline::render() {
|
||||
this->renderScene(this->renderManager->game->scene);
|
||||
}
|
||||
|
||||
void RenderPipeline::renderScene(Scene *scene) {
|
||||
auto backBuffer = this->renderManager->getBackBuffer();
|
||||
auto cameras = scene->findComponents<Camera>();
|
||||
Camera *backBufferCamera = nullptr;
|
||||
|
||||
// First, render all non-backbuffer cameras.
|
||||
auto it = cameras.begin();
|
||||
while(it != cameras.end()) {
|
||||
RenderTarget *cameraTarget = (*it)->getRenderTarget();
|
||||
|
||||
// Leave the backbuffer camera(s) to last, so we skip them.
|
||||
if(cameraTarget == backBuffer) {
|
||||
backBufferCamera = *it;
|
||||
} else {
|
||||
this->renderSceneCamera(scene, *it);
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
// Now render the backbuffer camera.
|
||||
if(backBufferCamera == nullptr) return;
|
||||
this->renderSceneCamera(scene, backBufferCamera);
|
||||
|
||||
// Now we try and render UI components
|
||||
auto uiCanvasList = scene->findComponents<UICanvas>();
|
||||
auto itCanvas = uiCanvasList.begin();
|
||||
while(itCanvas != uiCanvasList.end()) {
|
||||
this->renderUI(scene, backBufferCamera, *itCanvas);
|
||||
++itCanvas;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::renderSceneCamera(Scene *scene, Camera *camera) {
|
||||
RenderTarget *renderTarget = camera->getRenderTarget();
|
||||
renderTarget->bind();
|
||||
renderTarget->clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
this->renderManager->setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST |
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND
|
||||
);
|
||||
|
||||
auto meshes = scene->findComponents<MeshRenderer>();
|
||||
auto it = meshes.begin();
|
||||
while(it != meshes.end()) {
|
||||
auto mesh = *it;
|
||||
auto material = mesh->item->getComponent<Material>();
|
||||
|
||||
// TODO: fallback material?
|
||||
if(material == nullptr) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
auto shader = material->getShader();
|
||||
shader->bind();
|
||||
shader->setGlobalParameters(camera->projection, camera->transform->getWorldTransform());
|
||||
shader->setMeshParameters(mesh->item->transform.getWorldTransform());
|
||||
material->setShaderParameters();
|
||||
|
||||
mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPipeline::renderUI(
|
||||
Scene *scene,
|
||||
Camera *camera,
|
||||
UICanvas *canvas
|
||||
) {
|
||||
// Get the
|
||||
RenderTarget *renderTarget;
|
||||
|
||||
glm::mat4 transform;
|
||||
glm::mat4 projection;
|
||||
switch(canvas->drawType) {
|
||||
case UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE:
|
||||
transform = glm::mat4(1.0f);
|
||||
projection = glm::ortho(0.0f, canvas->getWidth(), canvas->getHeight(), 0.0f);
|
||||
renderTarget = camera->getRenderTarget();
|
||||
break;
|
||||
default:
|
||||
throw "UI Draw modes are not yet supported.";
|
||||
}
|
||||
|
||||
// Clear / Bind / Update the render target.
|
||||
renderTarget->bind();
|
||||
renderTarget->clear(
|
||||
RENDER_TARGET_CLEAR_FLAG_DEPTH |
|
||||
RENDER_TARGET_CLEAR_FLAG_COLOR
|
||||
);
|
||||
this->renderManager->setRenderFlags(
|
||||
RENDER_MANAGER_RENDER_FLAG_BLEND |
|
||||
RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST
|
||||
);
|
||||
|
||||
// Prepare the UI Shader
|
||||
auto shader = this->renderManager->getUIShader();
|
||||
shader->bind();
|
||||
shader->setUICamera(transform, projection);
|
||||
|
||||
// Render the children
|
||||
glm::mat4 rootMatrix = canvas->transform->getWorldTransform();
|
||||
auto it = canvas->children.begin();
|
||||
while(it != canvas->children.end()) {
|
||||
(*it)->draw(shader, rootMatrix);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
RenderPipeline::~RenderPipeline() {
|
||||
|
||||
}
|
@ -1,72 +1,72 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/RenderManager.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "scene/components/Components.hpp"
|
||||
#include "scene/components/ui/UICanvas.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderPipeline {
|
||||
public:
|
||||
RenderManager &renderManager;
|
||||
|
||||
/**
|
||||
* Constructs a new RenderPipeline. Render Pipelines are my attempt to
|
||||
* create both a flexible, but standard way to allow the individual games
|
||||
* to decide how they want to render the common scene-item models.
|
||||
*
|
||||
* @param renderManager Parent render manager this pipeline belongs to.
|
||||
*/
|
||||
RenderPipeline(RenderManager &renderManager);
|
||||
|
||||
/**
|
||||
* Initialize the render pipeline.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Renders the games' currently active scene, and all of its' cameras.
|
||||
*/
|
||||
virtual void render();
|
||||
|
||||
/**
|
||||
* Render a specific scene, usually just called for the currently active
|
||||
* scene, but in future this could include sub-scenes.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
*/
|
||||
virtual void renderScene(Scene &scene);
|
||||
|
||||
/**
|
||||
* Render a specific camera on a specific scene.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
* @param camera Camera within the scene to render.
|
||||
*/
|
||||
virtual void renderSceneCamera(Scene &scene, Camera &camera);
|
||||
|
||||
/**
|
||||
* Renders a UI Canvas to the back buffer.
|
||||
*
|
||||
* @param scene Scene for the UI canvas.
|
||||
* @param camera Main backbuffer camera for the canvas.
|
||||
* @param canvas Canvas to render.
|
||||
*/
|
||||
virtual void renderUI(
|
||||
Scene &scene,
|
||||
Camera &camera,
|
||||
UICanvas &canvas
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleanup a render pipeline that has been initialized.
|
||||
*/
|
||||
virtual ~RenderPipeline();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/RenderManager.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "scene/components/Components.hpp"
|
||||
#include "scene/components/ui/UICanvas.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class RenderPipeline {
|
||||
public:
|
||||
RenderManager *renderManager;
|
||||
|
||||
/**
|
||||
* Constructs a new RenderPipeline. Render Pipelines are my attempt to
|
||||
* create both a flexible, but standard way to allow the individual games
|
||||
* to decide how they want to render the common scene-item models.
|
||||
*
|
||||
* @param renderManager Parent render manager this pipeline belongs to.
|
||||
*/
|
||||
RenderPipeline(RenderManager *renderManager);
|
||||
|
||||
/**
|
||||
* Initialize the render pipeline.
|
||||
*/
|
||||
virtual void init();
|
||||
|
||||
/**
|
||||
* Renders the games' currently active scene, and all of its' cameras.
|
||||
*/
|
||||
virtual void render();
|
||||
|
||||
/**
|
||||
* Render a specific scene, usually just called for the currently active
|
||||
* scene, but in future this could include sub-scenes.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
*/
|
||||
virtual void renderScene(Scene *scene);
|
||||
|
||||
/**
|
||||
* Render a specific camera on a specific scene.
|
||||
*
|
||||
* @param scene Scene to render.
|
||||
* @param camera Camera within the scene to render.
|
||||
*/
|
||||
virtual void renderSceneCamera(Scene *scene, Camera *camera);
|
||||
|
||||
/**
|
||||
* Renders a UI Canvas to the back buffer.
|
||||
*
|
||||
* @param scene Scene for the UI canvas.
|
||||
* @param camera Main backbuffer camera for the canvas.
|
||||
* @param canvas Canvas to render.
|
||||
*/
|
||||
virtual void renderUI(
|
||||
Scene *scene,
|
||||
Camera *camera,
|
||||
UICanvas *canvas
|
||||
);
|
||||
|
||||
/**
|
||||
* Cleanup a render pipeline that has been initialized.
|
||||
*/
|
||||
virtual ~RenderPipeline();
|
||||
};
|
||||
}
|
@ -1,58 +1,58 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/flag.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
#define RENDER_TARGET_CLEAR_FLAG_COLOR FLAG_DEFINE(0)
|
||||
#define RENDER_TARGET_CLEAR_FLAG_DEPTH FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
class RenderTarget {
|
||||
public:
|
||||
Event<RenderTarget &, float_t, float_t> eventRenderTargetResized;
|
||||
|
||||
/**
|
||||
* Return the width of the render target.
|
||||
*
|
||||
* @return The width of the render target.
|
||||
*/
|
||||
virtual float_t getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Return the height of the render target.
|
||||
*
|
||||
* @return The height of the render target.
|
||||
*/
|
||||
virtual float_t getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Sets the clear color of the render target when the clear method for
|
||||
* the color buffer is requested.
|
||||
*
|
||||
* @param color Color to use for the clear operation.
|
||||
*/
|
||||
virtual void setClearColor(struct Color color) = 0;
|
||||
|
||||
/**
|
||||
* Request the existing data in the render target to be cleared out. We
|
||||
* typically assume the render target can support multiple buffer types,
|
||||
* so you can opt to only clear certain buffer types.
|
||||
*
|
||||
* @param clearFlags Flags to request what is going to be cleared.
|
||||
*/
|
||||
virtual void clear(flag8_t clearFlags) = 0;
|
||||
|
||||
/**
|
||||
* Bind the render target for rendering to. The proceeding render requests
|
||||
* will want to render to this render target directly. In future I may
|
||||
* see if we can have multiple render targets bound at once to make this
|
||||
* operation perform faster.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "util/flag.hpp"
|
||||
#include "display/Color.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
#define RENDER_TARGET_CLEAR_FLAG_COLOR FLAG_DEFINE(0)
|
||||
#define RENDER_TARGET_CLEAR_FLAG_DEPTH FLAG_DEFINE(1)
|
||||
|
||||
namespace Dawn {
|
||||
class RenderTarget {
|
||||
public:
|
||||
Event<RenderTarget*, float_t, float_t> eventRenderTargetResized;
|
||||
|
||||
/**
|
||||
* Return the width of the render target.
|
||||
*
|
||||
* @return The width of the render target.
|
||||
*/
|
||||
virtual float_t getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Return the height of the render target.
|
||||
*
|
||||
* @return The height of the render target.
|
||||
*/
|
||||
virtual float_t getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Sets the clear color of the render target when the clear method for
|
||||
* the color buffer is requested.
|
||||
*
|
||||
* @param color Color to use for the clear operation.
|
||||
*/
|
||||
virtual void setClearColor(struct Color color) = 0;
|
||||
|
||||
/**
|
||||
* Request the existing data in the render target to be cleared out. We
|
||||
* typically assume the render target can support multiple buffer types,
|
||||
* so you can opt to only clear certain buffer types.
|
||||
*
|
||||
* @param clearFlags Flags to request what is going to be cleared.
|
||||
*/
|
||||
virtual void clear(flag8_t clearFlags) = 0;
|
||||
|
||||
/**
|
||||
* Bind the render target for rendering to. The proceeding render requests
|
||||
* will want to render to this render target directly. In future I may
|
||||
* see if we can have multiple render targets bound at once to make this
|
||||
* operation perform faster.
|
||||
*/
|
||||
virtual void bind() = 0;
|
||||
};
|
||||
}
|
@ -1,160 +1,161 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Transform.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Transform::Transform(SceneItem &item) :
|
||||
item(item),
|
||||
transformLocal(1.0f),
|
||||
transformWorld(1.0f)
|
||||
{
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateLocalValuesFromLocalTransform() {
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(
|
||||
this->transformLocal,
|
||||
this->localScale,
|
||||
this->localRotation,
|
||||
this->localPosition,
|
||||
skew, perspective
|
||||
);
|
||||
}
|
||||
|
||||
void Transform::updateLocalTransformFromLocalValues() {
|
||||
glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition);
|
||||
glm::mat4 rotate = glm::mat4_cast(this->localRotation);
|
||||
glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale);
|
||||
this->transformLocal = translate * rotate * scale;
|
||||
this->updateWorldTransformFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateWorldTransformFromLocalTransform() {
|
||||
glm::mat4 newWorld(1.0f);
|
||||
auto parent = this->getParent();
|
||||
if(parent != nullptr) newWorld = parent->getWorldTransform();
|
||||
this->transformWorld = newWorld * transformLocal;
|
||||
}
|
||||
|
||||
void Transform::updateLocalTransformFromWorldTransform() {
|
||||
glm::mat4 parentMat(1.0f);
|
||||
auto parent = this->getParent();
|
||||
if(parent != nullptr) parentMat = parent->getWorldTransform();
|
||||
this->transformLocal = parentMat / this->transformWorld;
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateChildrenTransforms() {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*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, glm::vec3 up) {
|
||||
this->setWorldTransform(glm::lookAt(pos, look, up));
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 Transform::getLocalPosition() {
|
||||
return this->localPosition;
|
||||
}
|
||||
|
||||
void Transform::setLocalPosition(glm::vec3 position) {
|
||||
this->localPosition = position;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::vec3 Transform::getLocalScale() {
|
||||
return this->localScale;
|
||||
}
|
||||
|
||||
void Transform::setLocalScale(glm::vec3 scale) {
|
||||
this->localScale = scale;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::quat Transform::getLocalRotation() {
|
||||
return this->localRotation;
|
||||
}
|
||||
|
||||
void Transform::setLocalRotation(glm::quat rotation) {
|
||||
this->localRotation = rotation;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Transform::getLocalTransform() {
|
||||
return this->transformLocal;
|
||||
}
|
||||
|
||||
void Transform::setLocalTransform(glm::mat4 transform) {
|
||||
this->transformLocal = transform;
|
||||
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::mat4 Transform::getWorldTransform() {
|
||||
return this->transformWorld;
|
||||
}
|
||||
|
||||
void Transform::setWorldTransform(glm::mat4 transform) {
|
||||
this->transformWorld = transform;
|
||||
this->updateLocalTransformFromWorldTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
|
||||
void Transform::setParent(Transform *parent) {
|
||||
if(parent == this) throw "Cannot self reference";
|
||||
|
||||
auto currentParent = this->getParent();
|
||||
if(currentParent == parent) return;
|
||||
|
||||
if(currentParent != nullptr) {
|
||||
auto it = currentParent->children.begin();
|
||||
while(it != currentParent->children.end()) {
|
||||
if(*it == this) {
|
||||
currentParent->children.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
this->parent = parent;
|
||||
if(parent != nullptr) parent->children.push_back(this);
|
||||
|
||||
this->updateLocalTransformFromWorldTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
Transform * Transform::getParent() {
|
||||
return this->parent;
|
||||
}
|
||||
|
||||
Transform::~Transform() {
|
||||
this->setParent(nullptr);
|
||||
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->setParent(nullptr);
|
||||
++it;
|
||||
}
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Transform.hpp"
|
||||
#include "scene/SceneItem.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Transform::Transform(SceneItem *item) :
|
||||
transformLocal(1.0f),
|
||||
transformWorld(1.0f)
|
||||
{
|
||||
assertNotNull(item);
|
||||
this->item = item;
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateLocalValuesFromLocalTransform() {
|
||||
glm::vec3 skew;
|
||||
glm::vec4 perspective;
|
||||
glm::decompose(
|
||||
this->transformLocal,
|
||||
this->localScale,
|
||||
this->localRotation,
|
||||
this->localPosition,
|
||||
skew, perspective
|
||||
);
|
||||
}
|
||||
|
||||
void Transform::updateLocalTransformFromLocalValues() {
|
||||
glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition);
|
||||
glm::mat4 rotate = glm::mat4_cast(this->localRotation);
|
||||
glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale);
|
||||
this->transformLocal = translate * rotate * scale;
|
||||
this->updateWorldTransformFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateWorldTransformFromLocalTransform() {
|
||||
glm::mat4 newWorld(1.0f);
|
||||
auto parent = this->getParent();
|
||||
if(parent != nullptr) newWorld = parent->getWorldTransform();
|
||||
this->transformWorld = newWorld * transformLocal;
|
||||
}
|
||||
|
||||
void Transform::updateLocalTransformFromWorldTransform() {
|
||||
glm::mat4 parentMat(1.0f);
|
||||
auto parent = this->getParent();
|
||||
if(parent != nullptr) parentMat = parent->getWorldTransform();
|
||||
this->transformLocal = parentMat / this->transformWorld;
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
}
|
||||
|
||||
void Transform::updateChildrenTransforms() {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*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, glm::vec3 up) {
|
||||
this->setWorldTransform(glm::lookAt(pos, look, up));
|
||||
}
|
||||
|
||||
|
||||
glm::vec3 Transform::getLocalPosition() {
|
||||
return this->localPosition;
|
||||
}
|
||||
|
||||
void Transform::setLocalPosition(glm::vec3 position) {
|
||||
this->localPosition = position;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::vec3 Transform::getLocalScale() {
|
||||
return this->localScale;
|
||||
}
|
||||
|
||||
void Transform::setLocalScale(glm::vec3 scale) {
|
||||
this->localScale = scale;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::quat Transform::getLocalRotation() {
|
||||
return this->localRotation;
|
||||
}
|
||||
|
||||
void Transform::setLocalRotation(glm::quat rotation) {
|
||||
this->localRotation = rotation;
|
||||
this->updateLocalTransformFromLocalValues();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
|
||||
glm::mat4 Transform::getLocalTransform() {
|
||||
return this->transformLocal;
|
||||
}
|
||||
|
||||
void Transform::setLocalTransform(glm::mat4 transform) {
|
||||
this->transformLocal = transform;
|
||||
|
||||
this->updateLocalValuesFromLocalTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
glm::mat4 Transform::getWorldTransform() {
|
||||
return this->transformWorld;
|
||||
}
|
||||
|
||||
void Transform::setWorldTransform(glm::mat4 transform) {
|
||||
this->transformWorld = transform;
|
||||
this->updateLocalTransformFromWorldTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
|
||||
void Transform::setParent(Transform *parent) {
|
||||
assertTrue(parent != this);
|
||||
|
||||
auto currentParent = this->getParent();
|
||||
if(currentParent == parent) return;
|
||||
|
||||
if(currentParent != nullptr) {
|
||||
auto it = currentParent->children.begin();
|
||||
while(it != currentParent->children.end()) {
|
||||
if(*it == this) {
|
||||
currentParent->children.erase(it);
|
||||
break;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
this->parent = parent;
|
||||
if(parent != nullptr) parent->children.push_back(this);
|
||||
|
||||
this->updateLocalTransformFromWorldTransform();
|
||||
this->updateChildrenTransforms();
|
||||
}
|
||||
|
||||
Transform * Transform::getParent() {
|
||||
return this->parent;
|
||||
}
|
||||
|
||||
Transform::~Transform() {
|
||||
this->setParent(nullptr);
|
||||
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->setParent(nullptr);
|
||||
++it;
|
||||
}
|
||||
}
|
@ -1,145 +1,146 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/flag.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
|
||||
class Transform : public std::enable_shared_from_this<Transform> {
|
||||
private:
|
||||
// Local (real) values
|
||||
glm::vec3 localPosition;
|
||||
glm::vec3 localScale;
|
||||
glm::quat localRotation;
|
||||
|
||||
// Cached (non-real) values
|
||||
glm::mat4 transformLocal;
|
||||
glm::mat4 transformWorld;
|
||||
|
||||
// glm::vec3 position;
|
||||
// glm::vec3 scale;
|
||||
// glm::quat rotation;
|
||||
|
||||
// Heirarchy
|
||||
Transform *parent = nullptr;
|
||||
std::vector<Transform *> children;
|
||||
|
||||
// Hidden methods
|
||||
void updateLocalValuesFromLocalTransform();
|
||||
void updateLocalTransformFromLocalValues();
|
||||
void updateWorldTransformFromLocalTransform();
|
||||
void updateLocalTransformFromWorldTransform();
|
||||
void updateChildrenTransforms();
|
||||
|
||||
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
|
||||
* disconnected from each other, for example I really could use a special
|
||||
* 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.
|
||||
*/
|
||||
Transform(SceneItem &item);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
glm::vec3 getLocalPosition();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Retusn the scale of this item, relative to my parent.
|
||||
* @return 3D Scale vector of this item in parent-relative space.
|
||||
*/
|
||||
glm::vec3 getLocalScale();
|
||||
|
||||
/**
|
||||
* Set the local scale of this item.
|
||||
* @param scale Scale of this item, relative to its parent.
|
||||
*/
|
||||
void setLocalScale(glm::vec3 scale);
|
||||
|
||||
/**
|
||||
* Returns the local rotation for this transform.
|
||||
* @return The local rotation (parent-relative).
|
||||
*/
|
||||
glm::quat getLocalRotation();
|
||||
|
||||
/**
|
||||
* Set the local (parent-relative) rotation for this transform.
|
||||
* @param rotation Rotation in parent relative space.
|
||||
*/
|
||||
void setLocalRotation(glm::quat rotation);
|
||||
|
||||
/**
|
||||
* Returns the transform matrix for this transform, in parent-relative
|
||||
* space.
|
||||
* @return The transform origin in parent-relative space.
|
||||
*/
|
||||
glm::mat4 getLocalTransform();
|
||||
|
||||
/**
|
||||
* Sets the local transform matrix for this transform.
|
||||
* @param transform Local (parent-relative) transform to set.
|
||||
*/
|
||||
void setLocalTransform(glm::mat4 transform);
|
||||
|
||||
/**
|
||||
* Returns the transformation matrix for this transform, in world-space.
|
||||
* @return The transform origin in world-space.
|
||||
*/
|
||||
glm::mat4 getWorldTransform();
|
||||
|
||||
/**
|
||||
* Updates the transform's world-space.
|
||||
* @param transform Sets the transform position in world-space.
|
||||
*/
|
||||
void setWorldTransform(glm::mat4 transform);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void setParent(Transform *p);
|
||||
|
||||
/**
|
||||
* Returns the parent transform of this transform, or nullptr if there is
|
||||
* no parent for this transform.
|
||||
* @return Pointer to the parent transform, or nullptr.
|
||||
*/
|
||||
Transform * getParent();
|
||||
|
||||
/**
|
||||
* Dispose and clenaup this transform, also removes self from parent.
|
||||
*/
|
||||
~Transform();
|
||||
|
||||
friend SceneItem;
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "util/flag.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
|
||||
class Transform {
|
||||
private:
|
||||
// Local (real) values
|
||||
glm::vec3 localPosition;
|
||||
glm::vec3 localScale;
|
||||
glm::quat localRotation;
|
||||
|
||||
// Cached (non-real) values
|
||||
glm::mat4 transformLocal;
|
||||
glm::mat4 transformWorld;
|
||||
|
||||
// glm::vec3 position;
|
||||
// glm::vec3 scale;
|
||||
// glm::quat rotation;
|
||||
|
||||
// Heirarchy
|
||||
Transform *parent = nullptr;
|
||||
std::vector<Transform *> children;
|
||||
|
||||
// Hidden methods
|
||||
void updateLocalValuesFromLocalTransform();
|
||||
void updateLocalTransformFromLocalValues();
|
||||
void updateWorldTransformFromLocalTransform();
|
||||
void updateLocalTransformFromWorldTransform();
|
||||
void updateChildrenTransforms();
|
||||
|
||||
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
|
||||
* disconnected from each other, for example I really could use a special
|
||||
* 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.
|
||||
*/
|
||||
Transform(SceneItem *item);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
glm::vec3 getLocalPosition();
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Retusn the scale of this item, relative to my parent.
|
||||
* @return 3D Scale vector of this item in parent-relative space.
|
||||
*/
|
||||
glm::vec3 getLocalScale();
|
||||
|
||||
/**
|
||||
* Set the local scale of this item.
|
||||
* @param scale Scale of this item, relative to its parent.
|
||||
*/
|
||||
void setLocalScale(glm::vec3 scale);
|
||||
|
||||
/**
|
||||
* Returns the local rotation for this transform.
|
||||
* @return The local rotation (parent-relative).
|
||||
*/
|
||||
glm::quat getLocalRotation();
|
||||
|
||||
/**
|
||||
* Set the local (parent-relative) rotation for this transform.
|
||||
* @param rotation Rotation in parent relative space.
|
||||
*/
|
||||
void setLocalRotation(glm::quat rotation);
|
||||
|
||||
/**
|
||||
* Returns the transform matrix for this transform, in parent-relative
|
||||
* space.
|
||||
* @return The transform origin in parent-relative space.
|
||||
*/
|
||||
glm::mat4 getLocalTransform();
|
||||
|
||||
/**
|
||||
* Sets the local transform matrix for this transform.
|
||||
* @param transform Local (parent-relative) transform to set.
|
||||
*/
|
||||
void setLocalTransform(glm::mat4 transform);
|
||||
|
||||
/**
|
||||
* Returns the transformation matrix for this transform, in world-space.
|
||||
* @return The transform origin in world-space.
|
||||
*/
|
||||
glm::mat4 getWorldTransform();
|
||||
|
||||
/**
|
||||
* Updates the transform's world-space.
|
||||
* @param transform Sets the transform position in world-space.
|
||||
*/
|
||||
void setWorldTransform(glm::mat4 transform);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void setParent(Transform *p);
|
||||
|
||||
/**
|
||||
* Returns the parent transform of this transform, or nullptr if there is
|
||||
* no parent for this transform.
|
||||
* @return Pointer to the parent transform, or nullptr.
|
||||
*/
|
||||
Transform * getParent();
|
||||
|
||||
/**
|
||||
* Dispose and clenaup this transform, also removes self from parent.
|
||||
*/
|
||||
~Transform();
|
||||
|
||||
friend SceneItem;
|
||||
};
|
||||
}
|
@ -1,86 +1,89 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "RenderTarget.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/flag.hpp"
|
||||
|
||||
#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0)
|
||||
#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1)
|
||||
|
||||
typedef flag_t renderflag_t;
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
class RenderPipeline;
|
||||
|
||||
class IRenderManager {
|
||||
protected:
|
||||
renderflag_t renderFlags = 0;
|
||||
|
||||
public:
|
||||
DawnGame &game;
|
||||
std::shared_ptr<RenderPipeline> renderPipeline;
|
||||
|
||||
/**
|
||||
* Default constructor for a render manager instance.
|
||||
*
|
||||
* @param game Game that this render manager belongs to.
|
||||
*/
|
||||
IRenderManager(DawnGame &game) : game(game) {}
|
||||
|
||||
/**
|
||||
* Returns the primary render target (the backbuffer) that draws directly
|
||||
* to the screen.
|
||||
*
|
||||
* @return Shared pointer to the backbuffer render target.
|
||||
*/
|
||||
virtual RenderTarget & getBackBuffer() = 0;
|
||||
|
||||
/**
|
||||
* Returns the current render pipeline intended to be used for rendering
|
||||
* the currently active scene on the game instance.
|
||||
*
|
||||
* @return Reference to the currently active main scene render pipeline.
|
||||
*/
|
||||
virtual RenderPipeline & getRenderPipeline() = 0;
|
||||
|
||||
/**
|
||||
* Returns the default shader, the default shader will be applied to the
|
||||
* materials first.
|
||||
*
|
||||
* @return Reference to the default shader.
|
||||
*/
|
||||
virtual std::shared_ptr<Shader> getDefaultShader() = 0;
|
||||
|
||||
/**
|
||||
* Returns the UI Shader used by the game's UI engine.
|
||||
*
|
||||
* @return Pointer to the UI Shader.
|
||||
*/
|
||||
virtual std::shared_ptr<UIShader> getUIShader() = 0;
|
||||
|
||||
/**
|
||||
* Sets the render flags for the render manager to use.
|
||||
*
|
||||
* @param renderFlags Render flags to use.
|
||||
*/
|
||||
virtual void setRenderFlags(renderflag_t renderFlags) = 0;
|
||||
|
||||
/**
|
||||
* Initialize / Start the Render Manager.
|
||||
*
|
||||
* @param game Game instance this render manager belongs to.
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Perform a synchronous frame update on the render manager.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "RenderTarget.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
#include "display/shader/UIShader.hpp"
|
||||
#include "util/flag.hpp"
|
||||
|
||||
#define RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST FLAG_DEFINE(0)
|
||||
#define RENDER_MANAGER_RENDER_FLAG_BLEND FLAG_DEFINE(1)
|
||||
|
||||
typedef flag_t renderflag_t;
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
class RenderPipeline;
|
||||
|
||||
class IRenderManager {
|
||||
protected:
|
||||
renderflag_t renderFlags = 0;
|
||||
|
||||
public:
|
||||
DawnGame *game;
|
||||
RenderPipeline *renderPipeline;
|
||||
|
||||
/**
|
||||
* Default constructor for a render manager instance.
|
||||
*
|
||||
* @param game Game that this render manager belongs to.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
virtual RenderTarget * getBackBuffer() = 0;
|
||||
|
||||
/**
|
||||
* Returns the current render pipeline intended to be used for rendering
|
||||
* the currently active scene on the game instance.
|
||||
*
|
||||
* @return Reference to the currently active main scene render pipeline.
|
||||
*/
|
||||
virtual RenderPipeline * getRenderPipeline() = 0;
|
||||
|
||||
/**
|
||||
* Returns the default shader, the default shader will be applied to the
|
||||
* materials first.
|
||||
*
|
||||
* @return Reference to the default shader.
|
||||
*/
|
||||
virtual Shader * getDefaultShader() = 0;
|
||||
|
||||
/**
|
||||
* Returns the UI Shader used by the game's UI engine.
|
||||
*
|
||||
* @return Pointer to the UI Shader.
|
||||
*/
|
||||
virtual UIShader * getUIShader() = 0;
|
||||
|
||||
/**
|
||||
* Sets the render flags for the render manager to use.
|
||||
*
|
||||
* @param renderFlags Render flags to use.
|
||||
*/
|
||||
virtual void setRenderFlags(renderflag_t renderFlags) = 0;
|
||||
|
||||
/**
|
||||
* Initialize / Start the Render Manager.
|
||||
*
|
||||
* @param game Game instance this render manager belongs to.
|
||||
*/
|
||||
virtual void init() = 0;
|
||||
|
||||
/**
|
||||
* Perform a synchronous frame update on the render manager.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
};
|
||||
}
|
@ -1,19 +1,58 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Color.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ITexture {
|
||||
public:
|
||||
virtual int32_t getWidth() = 0;
|
||||
virtual int32_t getHeight() = 0;
|
||||
virtual void setSize(int32_t width, int32_t height) = 0;
|
||||
virtual void fill(struct Color) = 0;
|
||||
virtual bool_t isReady() = 0;
|
||||
virtual void buffer(struct Color pixels[]) = 0;
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/Color.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class ITexture {
|
||||
public:
|
||||
/**
|
||||
* Returns the width of the texture.
|
||||
*
|
||||
* @return Width of the texture.
|
||||
*/
|
||||
virtual int32_t getWidth() = 0;
|
||||
|
||||
/**
|
||||
* Returns the height of the texture.
|
||||
*
|
||||
* @return Height of the texture.
|
||||
*/
|
||||
virtual int32_t getHeight() = 0;
|
||||
|
||||
/**
|
||||
* Initializes a texture.
|
||||
*
|
||||
* @param width Width of the texture (in pixels).
|
||||
* @param height Height of the texture (in pixels).
|
||||
*/
|
||||
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;
|
||||
};
|
||||
}
|
@ -1,34 +1,72 @@
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "FontMeasure.hpp"
|
||||
|
||||
#define FONT_NEWLINE '\n'
|
||||
#define FONT_SPACE ' '
|
||||
|
||||
namespace Dawn {
|
||||
class Font {
|
||||
public:
|
||||
virtual void buffer(
|
||||
std::string text,
|
||||
float_t fontSize,
|
||||
float_t maxWidth,
|
||||
Mesh &mesh,
|
||||
struct FontMeasure *info
|
||||
) = 0;
|
||||
|
||||
virtual Texture & getTexture() = 0;
|
||||
virtual void draw(Mesh &mesh, int32_t startCharacter, int32_t length) = 0;
|
||||
virtual float_t getLineHeight(float_t fontSize) = 0;
|
||||
virtual float_t getDefaultFontSize() = 0;
|
||||
};
|
||||
/**
|
||||
* Copyright (c) 2022 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
#include "display/mesh/QuadMesh.hpp"
|
||||
#include "FontMeasure.hpp"
|
||||
|
||||
#define FONT_NEWLINE '\n'
|
||||
#define FONT_SPACE ' '
|
||||
|
||||
namespace Dawn {
|
||||
class Font {
|
||||
public:
|
||||
/**
|
||||
* Buffer the characters of a string onto a primitive and get the result of the
|
||||
* buffer back as a resulting generic measurement information structure. Note
|
||||
* that measure is REQUIRED, and must be DISPOSED after it has been calculated.
|
||||
*
|
||||
* @param text String to buffer.
|
||||
* @param fontSize Font size to use for the buffer operation.
|
||||
* @param maxWidth Maximum width (in pixels) to use to textwrap. -1 for no wrap.
|
||||
* @param mesh Mesh to buffer the string on to.
|
||||
* @param info Pointer to where you want to store resulting measurements.
|
||||
*/
|
||||
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;
|
||||
};
|
||||
}
|
@ -1,43 +1,50 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "FontMeasure.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
float_t FontMeasure::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
float_t FontMeasure::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadCount() {
|
||||
return this->realLength;
|
||||
}
|
||||
|
||||
float_t FontMeasure::getHeightOfLineCount(int32_t lineCount) {
|
||||
return this->lineHeight * lineCount;
|
||||
}
|
||||
|
||||
size_t FontMeasure::getLineCount() {
|
||||
return this->lines.size();
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadsOnLine(int32_t line) {
|
||||
return this->lines[line].length;
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadIndexOnLine(int32_t line) {
|
||||
return this->lines[line].start;
|
||||
}
|
||||
|
||||
void FontMeasure::addLine(int32_t start, int32_t len) {
|
||||
struct FontLineMeasure info;
|
||||
info.start = start;
|
||||
info.length = len;
|
||||
this->lines.push_back(info);
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "FontMeasure.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
float_t FontMeasure::getWidth() {
|
||||
return this->width;
|
||||
}
|
||||
|
||||
float_t FontMeasure::getHeight() {
|
||||
return this->height;
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadCount() {
|
||||
return this->realLength;
|
||||
}
|
||||
|
||||
float_t FontMeasure::getHeightOfLineCount(int32_t lineCount) {
|
||||
assertTrue(lineCount > 0);
|
||||
return this->lineHeight * lineCount;
|
||||
}
|
||||
|
||||
size_t FontMeasure::getLineCount() {
|
||||
return this->lines.size();
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadsOnLine(int32_t line) {
|
||||
assertTrue(line >= 0);
|
||||
assertTrue(line < this->lines.size());
|
||||
return this->lines[line].length;
|
||||
}
|
||||
|
||||
int32_t FontMeasure::getQuadIndexOnLine(int32_t line) {
|
||||
assertTrue(line >= 0);
|
||||
assertTrue(line < this->lines.size());
|
||||
return this->lines[line].start;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
@ -1,50 +1,51 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct FontLineMeasure {
|
||||
/** What (real character) index the line starts at */
|
||||
int32_t start;
|
||||
/** How many (real) characters the line is in length */
|
||||
int32_t length;
|
||||
};
|
||||
|
||||
struct FontMeasure {
|
||||
public:
|
||||
/** How many raw chars are in the string */
|
||||
int32_t length;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Dimensions of the string */
|
||||
float_t width, height;
|
||||
|
||||
/** Height of a single line */
|
||||
float_t lineHeight;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void addLine(int32_t start, int32_t length);
|
||||
|
||||
float_t getWidth();
|
||||
float_t getHeight();
|
||||
int32_t getQuadsOnLine(int32_t line);
|
||||
int32_t getQuadIndexOnLine(int32_t line);
|
||||
float_t getHeightOfLineCount(int32_t lineCount);
|
||||
size_t getLineCount();
|
||||
int32_t getQuadCount();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct FontLineMeasure {
|
||||
/** What (real character) index the line starts at */
|
||||
int32_t start;
|
||||
/** How many (real) characters the line is in length */
|
||||
int32_t length;
|
||||
};
|
||||
|
||||
struct FontMeasure {
|
||||
public:
|
||||
/** How many raw chars are in the string */
|
||||
int32_t length;
|
||||
|
||||
/** 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;
|
||||
|
||||
/** Dimensions of the string */
|
||||
float_t width, height;
|
||||
|
||||
/** Height of a single line */
|
||||
float_t lineHeight;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
void addLine(int32_t start, int32_t length);
|
||||
|
||||
float_t getWidth();
|
||||
float_t getHeight();
|
||||
int32_t getQuadsOnLine(int32_t line);
|
||||
int32_t getQuadIndexOnLine(int32_t line);
|
||||
float_t getHeightOfLineCount(int32_t lineCount);
|
||||
size_t getLineCount();
|
||||
int32_t getQuadCount();
|
||||
};
|
||||
}
|
@ -13,6 +13,12 @@
|
||||
using namespace Dawn;
|
||||
|
||||
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(
|
||||
this->characterData,
|
||||
this->texture.getWidth(), this->texture.getHeight(),
|
||||
@ -40,11 +46,15 @@ void TrueTypeFont::buffer(
|
||||
std::string text,
|
||||
float_t fontSize,
|
||||
float_t maxWidth,
|
||||
Mesh &mesh,
|
||||
Mesh *mesh,
|
||||
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) {
|
||||
info->length = 0;
|
||||
info->realLength = 0;
|
||||
@ -53,15 +63,18 @@ void TrueTypeFont::buffer(
|
||||
info->width = 0;
|
||||
info->height = 0.0f;
|
||||
info->lineHeight = 0.0f;
|
||||
mesh.createBuffers(0, 0);
|
||||
mesh->createBuffers(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
auto quads = new truetypequad_t[stringLength];
|
||||
assertNotNull(quads);
|
||||
|
||||
// Get the font scale
|
||||
auto scale = this->getScale(fontSize);
|
||||
|
||||
assertTrue(scale > 0);
|
||||
|
||||
// Adjust the max width to match the scale, and allow "no max width".
|
||||
maxWidth = maxWidth == -1 ? 9999999 : maxWidth * (1 / scale);
|
||||
|
||||
@ -143,7 +156,7 @@ void TrueTypeFont::buffer(
|
||||
}
|
||||
|
||||
// Initialize primitive
|
||||
mesh.createBuffers(
|
||||
mesh->createBuffers(
|
||||
QUAD_VERTICE_COUNT * info->realLength,
|
||||
QUAD_INDICE_COUNT * info->realLength
|
||||
);
|
||||
@ -163,7 +176,7 @@ void TrueTypeFont::buffer(
|
||||
info->height = mathMax<float_t>(info->height, quad->y1);
|
||||
|
||||
// Buffer the quad.
|
||||
QuadMesh::bufferQuadMesh(&mesh,
|
||||
QuadMesh::bufferQuadMesh(mesh,
|
||||
glm::vec2(quad->x0, quad->y0), glm::vec2(quad->s0, quad->t0),
|
||||
glm::vec2(quad->x1, quad->y1), glm::vec2(quad->s1, quad->t1),
|
||||
j * QUAD_VERTICE_COUNT, j * QUAD_INDICE_COUNT
|
||||
@ -173,12 +186,14 @@ void TrueTypeFont::buffer(
|
||||
delete quads;
|
||||
}
|
||||
|
||||
Texture & TrueTypeFont::getTexture() {
|
||||
return this->texture;
|
||||
Texture * TrueTypeFont::getTexture() {
|
||||
return &this->texture;
|
||||
}
|
||||
|
||||
void TrueTypeFont::draw(Mesh &mesh, int32_t startchar, int32_t length) {
|
||||
mesh.draw(
|
||||
void TrueTypeFont::draw(Mesh *mesh, int32_t startchar, int32_t length) {
|
||||
assertNotNull(mesh);
|
||||
|
||||
mesh->draw(
|
||||
MESH_DRAW_MODE_TRIANGLES,
|
||||
startchar * 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) {
|
||||
assertTrue(fontSize > 0);
|
||||
return 13.0f;
|
||||
}
|
||||
|
||||
float_t TrueTypeFont::getDefaultFontSize() {
|
||||
return (float_t)this->fontSize;
|
||||
}
|
||||
|
||||
}
|
@ -71,12 +71,11 @@ namespace Dawn {
|
||||
std::string text,
|
||||
float_t fontSize,
|
||||
float_t maxWidth,
|
||||
Mesh &mesh,
|
||||
Mesh *mesh,
|
||||
struct FontMeasure *info
|
||||
) override;
|
||||
|
||||
Texture & getTexture() override;
|
||||
void draw(Mesh &mesh, int32_t startCharacter, int32_t length) override;
|
||||
Texture * getTexture() override;
|
||||
void draw(Mesh *mesh, int32_t startCharacter, int32_t length) override;
|
||||
float_t getLineHeight(float_t fontSize) override;
|
||||
float_t getDefaultFontSize() override;
|
||||
};
|
||||
|
@ -1,64 +1,66 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "CubeMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void CubeMesh::buffer(
|
||||
Mesh &mesh,
|
||||
glm::vec3 pos, glm::vec3 size,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
mesh.bufferPositions(verticeStart, std::array<glm::vec3, CUBE_VERTICE_COUNT>{{
|
||||
pos,
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z),
|
||||
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
|
||||
|
||||
glm::vec3(pos.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
|
||||
pos + size
|
||||
}});
|
||||
|
||||
mesh.bufferCoordinates(verticeStart,std::array<glm::vec2,CUBE_VERTICE_COUNT>{{
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1),
|
||||
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1)
|
||||
}});
|
||||
|
||||
mesh.bufferIndices(indiceStart, std::array<meshindice_t, CUBE_INDICE_COUNT>{{
|
||||
// Back
|
||||
verticeStart, verticeStart + 1, verticeStart + 3,
|
||||
verticeStart, verticeStart + 2, verticeStart + 3,
|
||||
|
||||
// Right
|
||||
verticeStart + 1, verticeStart + 5, verticeStart + 7,
|
||||
verticeStart + 1, verticeStart + 3, verticeStart + 7,
|
||||
|
||||
// Left
|
||||
verticeStart + 4, verticeStart, verticeStart + 2,
|
||||
verticeStart + 4, verticeStart + 6, verticeStart + 2,
|
||||
|
||||
// Front
|
||||
verticeStart + 5, verticeStart + 4, verticeStart + 6,
|
||||
verticeStart + 5, verticeStart + 7, verticeStart + 6,
|
||||
|
||||
// Top
|
||||
verticeStart + 7, verticeStart + 2, verticeStart + 6,
|
||||
verticeStart + 7, verticeStart + 3, verticeStart + 2,
|
||||
|
||||
// Bottom
|
||||
verticeStart + 1, verticeStart, verticeStart + 4,
|
||||
verticeStart + 1, verticeStart + 4, verticeStart + 5
|
||||
}});
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "CubeMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void CubeMesh::buffer(
|
||||
Mesh *mesh,
|
||||
glm::vec3 pos, glm::vec3 size,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
assertNotNull(mesh);
|
||||
|
||||
mesh->bufferPositions(verticeStart, std::array<glm::vec3, CUBE_VERTICE_COUNT>{{
|
||||
pos,
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z),
|
||||
glm::vec3(pos.x+size.x, pos.y+size.y, pos.z),
|
||||
|
||||
glm::vec3(pos.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x+size.x, pos.y, pos.z+size.z),
|
||||
glm::vec3(pos.x, pos.y+size.y, pos.z+size.z),
|
||||
pos + size
|
||||
}});
|
||||
|
||||
mesh->bufferCoordinates(verticeStart,std::array<glm::vec2,CUBE_VERTICE_COUNT>{{
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1),
|
||||
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(1, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 1)
|
||||
}});
|
||||
|
||||
mesh->bufferIndices(indiceStart, std::array<meshindice_t, CUBE_INDICE_COUNT>{{
|
||||
// Back
|
||||
verticeStart, verticeStart + 1, verticeStart + 3,
|
||||
verticeStart, verticeStart + 2, verticeStart + 3,
|
||||
|
||||
// Right
|
||||
verticeStart + 1, verticeStart + 5, verticeStart + 7,
|
||||
verticeStart + 1, verticeStart + 3, verticeStart + 7,
|
||||
|
||||
// Left
|
||||
verticeStart + 4, verticeStart, verticeStart + 2,
|
||||
verticeStart + 4, verticeStart + 6, verticeStart + 2,
|
||||
|
||||
// Front
|
||||
verticeStart + 5, verticeStart + 4, verticeStart + 6,
|
||||
verticeStart + 5, verticeStart + 7, verticeStart + 6,
|
||||
|
||||
// Top
|
||||
verticeStart + 7, verticeStart + 2, verticeStart + 6,
|
||||
verticeStart + 7, verticeStart + 3, verticeStart + 2,
|
||||
|
||||
// Bottom
|
||||
verticeStart + 1, verticeStart, verticeStart + 4,
|
||||
verticeStart + 1, verticeStart + 4, verticeStart + 5
|
||||
}});
|
||||
}
|
@ -1,21 +1,21 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
#define CUBE_VERTICE_COUNT 8
|
||||
#define CUBE_INDICE_COUNT 36
|
||||
|
||||
namespace Dawn {
|
||||
class CubeMesh {
|
||||
public:
|
||||
static void buffer(
|
||||
Mesh &mesh,
|
||||
glm::vec3 pos, glm::vec3 size,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
);
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
#define CUBE_VERTICE_COUNT 8
|
||||
#define CUBE_INDICE_COUNT 36
|
||||
|
||||
namespace Dawn {
|
||||
class CubeMesh {
|
||||
public:
|
||||
static void buffer(
|
||||
Mesh *mesh,
|
||||
glm::vec3 pos, glm::vec3 size,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
);
|
||||
};
|
||||
}
|
@ -1,49 +1,51 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void QuadMesh::bufferQuadMeshWithZ(
|
||||
Mesh *mesh,
|
||||
glm::vec2 xy0, glm::vec2 uv0,
|
||||
glm::vec2 xy1, glm::vec2 uv1,
|
||||
float_t z, int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
mesh->bufferPositions(
|
||||
verticeStart, std::array<glm::vec3, QUAD_VERTICE_COUNT>{{
|
||||
glm::vec3(xy0, z),
|
||||
glm::vec3(xy1.x, xy0.y, z),
|
||||
glm::vec3(xy0.x, xy1.y, z),
|
||||
glm::vec3(xy1, z)
|
||||
}}
|
||||
);
|
||||
|
||||
mesh->bufferCoordinates(
|
||||
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,
|
||||
verticeStart + 1, verticeStart + 2, verticeStart + 3
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferQuadMesh(
|
||||
Mesh *mesh,
|
||||
glm::vec2 xy0, glm::vec2 uv0,
|
||||
glm::vec2 xy1, glm::vec2 uv1,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
QuadMesh::bufferQuadMeshWithZ(
|
||||
mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart
|
||||
);
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "QuadMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void QuadMesh::bufferQuadMeshWithZ(
|
||||
Mesh *mesh,
|
||||
glm::vec2 xy0, glm::vec2 uv0,
|
||||
glm::vec2 xy1, glm::vec2 uv1,
|
||||
float_t z, int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
assertNotNull(mesh);
|
||||
|
||||
mesh->bufferPositions(
|
||||
verticeStart, std::array<glm::vec3, QUAD_VERTICE_COUNT>{{
|
||||
glm::vec3(xy0, z),
|
||||
glm::vec3(xy1.x, xy0.y, z),
|
||||
glm::vec3(xy0.x, xy1.y, z),
|
||||
glm::vec3(xy1, z)
|
||||
}}
|
||||
);
|
||||
|
||||
mesh->bufferCoordinates(
|
||||
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,
|
||||
verticeStart + 1, verticeStart + 2, verticeStart + 3
|
||||
}}
|
||||
);
|
||||
}
|
||||
|
||||
void QuadMesh::bufferQuadMesh(
|
||||
Mesh *mesh,
|
||||
glm::vec2 xy0, glm::vec2 uv0,
|
||||
glm::vec2 xy1, glm::vec2 uv1,
|
||||
int32_t verticeStart, int32_t indiceStart
|
||||
) {
|
||||
QuadMesh::bufferQuadMeshWithZ(
|
||||
mesh, xy0, uv0, xy1, uv1, 0, verticeStart, indiceStart
|
||||
);
|
||||
}
|
@ -1,25 +1,27 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/mesh/TriangleMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void TriangleMesh::createTriangleMesh(Mesh &mesh) {
|
||||
mesh.createBuffers(3, 3);
|
||||
mesh.bufferPositions(0, std::array<glm::vec3, 3>{{
|
||||
glm::vec3(-0.5f, -0.5f, 0),
|
||||
glm::vec3(0.5f, -0.5f, 0),
|
||||
glm::vec3(0, 0.5f, 0)
|
||||
}});
|
||||
mesh.bufferCoordinates(0, std::array<glm::vec2, 3>{{
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 0)
|
||||
}});
|
||||
mesh.bufferIndices(0, std::array<meshindice_t,3>{{
|
||||
0, 1, 2
|
||||
}});
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "display/mesh/TriangleMesh.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
void TriangleMesh::createTriangleMesh(Mesh *mesh) {
|
||||
assertNotNull(mesh);
|
||||
|
||||
mesh->createBuffers(3, 3);
|
||||
mesh->bufferPositions(0, std::array<glm::vec3, 3>{{
|
||||
glm::vec3(-0.5f, -0.5f, 0),
|
||||
glm::vec3(0.5f, -0.5f, 0),
|
||||
glm::vec3(0, 0.5f, 0)
|
||||
}});
|
||||
mesh->bufferCoordinates(0, std::array<glm::vec2, 3>{{
|
||||
glm::vec2(0, 0),
|
||||
glm::vec2(0, 1),
|
||||
glm::vec2(1, 0)
|
||||
}});
|
||||
mesh->bufferIndices(0, std::array<meshindice_t,3>{{
|
||||
0, 1, 2
|
||||
}});
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TriangleMesh {
|
||||
public:
|
||||
/**
|
||||
* Initializes a mesh to hold a single triangle.
|
||||
*
|
||||
* @param mesh Mesh to initialize as a triangle.
|
||||
*/
|
||||
static void createTriangleMesh(Mesh &mesh);
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class TriangleMesh {
|
||||
public:
|
||||
/**
|
||||
* Initializes a mesh to hold a single triangle.
|
||||
*
|
||||
* @param mesh Mesh to initialize as a triangle.
|
||||
*/
|
||||
static void createTriangleMesh(Mesh *mesh);
|
||||
};
|
||||
}
|
@ -33,7 +33,7 @@ namespace Dawn {
|
||||
*
|
||||
* @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
|
||||
|
@ -1,119 +1,119 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
||||
template<typename... A>
|
||||
struct IEventListener {
|
||||
/**
|
||||
* Abstracted method for C++ template reasons. Invokes the listener.
|
||||
*
|
||||
* @param args Arguments to pass to the listener.
|
||||
*/
|
||||
virtual void invoke(A... args) = 0;
|
||||
};
|
||||
|
||||
template <class T, typename... A>
|
||||
struct EventListener : public IEventListener<A...> {
|
||||
T *instance;
|
||||
void (T::*callback)(A... args);
|
||||
|
||||
/**
|
||||
* Construct a new event listener structure.
|
||||
*
|
||||
* @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),
|
||||
callback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
void invoke(A... args) {
|
||||
((*this->instance).*(this->callback))(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename...A>
|
||||
class Event {
|
||||
private:
|
||||
std::vector<IEventListener<A...>*> listeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Add a listener to this event.
|
||||
*
|
||||
* @tparam T The class that will receive the event.
|
||||
* @param instance Instance of type T that will receive the callback.
|
||||
* @param callback Callback method attached to T to receive the event.
|
||||
* @return The initialized event listener. You don't really need this.
|
||||
*/
|
||||
template<class T>
|
||||
EventListener<T, A...> * addListener(
|
||||
T *instance,
|
||||
void (T::*callback)(A... args)
|
||||
) {
|
||||
auto listener = new EventListener<T,A...>(instance, callback);
|
||||
this->listeners.push_back(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event listener from this event.
|
||||
*
|
||||
* @tparam T The class that was once receiving the event.
|
||||
* @param instance Instance of type T that did receive the callback.
|
||||
* @param callback Callback method attached to T for the event.
|
||||
*/
|
||||
template<class T>
|
||||
void removeListener(
|
||||
T *instance,
|
||||
void (T::*callback)(A... args)
|
||||
) {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
auto listener = static_cast<EventListener<T,A...>*>(*it);
|
||||
|
||||
if(listener->instance != instance || listener->callback != callback) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
this->listeners.erase(it);
|
||||
delete listener;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the event and emits to all of the listeners.
|
||||
*
|
||||
* @param args Arguments for this event to pass to the listeners.
|
||||
*/
|
||||
void invoke(A... args) {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
(*it)->invoke(args...);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the event instance. Will also destroy all of the event
|
||||
* listeners.
|
||||
*/
|
||||
~Event() {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
delete *it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
||||
template<typename... A>
|
||||
struct IEventListener {
|
||||
/**
|
||||
* Abstracted method for C++ template reasons. Invokes the listener.
|
||||
*
|
||||
* @param args Arguments to pass to the listener.
|
||||
*/
|
||||
virtual void invoke(A... args) = 0;
|
||||
};
|
||||
|
||||
template <class T, typename... A>
|
||||
struct EventListener : public IEventListener<A...> {
|
||||
T *instance;
|
||||
void (T::*callback)(A... args);
|
||||
|
||||
/**
|
||||
* Construct a new event listener structure.
|
||||
*
|
||||
* @param instance Instance that the callback belongs to.
|
||||
* @param callback Callback method that invokes back.
|
||||
*/
|
||||
EventListener(T *instance, void (T::*callback)(A... args)) {
|
||||
this->instance = instance;
|
||||
this->callback = callback;
|
||||
}
|
||||
|
||||
void invoke(A... args) {
|
||||
((*this->instance).*(this->callback))(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename...A>
|
||||
class Event {
|
||||
private:
|
||||
std::vector<IEventListener<A...>*> listeners;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Add a listener to this event.
|
||||
*
|
||||
* @tparam T The class that will receive the event.
|
||||
* @param instance Instance of type T that will receive the callback.
|
||||
* @param callback Callback method attached to T to receive the event.
|
||||
* @return The initialized event listener. You don't really need this.
|
||||
*/
|
||||
template<class T>
|
||||
EventListener<T, A...> * addListener(
|
||||
T *instance,
|
||||
void (T::*callback)(A... args)
|
||||
) {
|
||||
auto listener = new EventListener<T,A...>(instance, callback);
|
||||
this->listeners.push_back(listener);
|
||||
return listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an event listener from this event.
|
||||
*
|
||||
* @tparam T The class that was once receiving the event.
|
||||
* @param instance Instance of type T that did receive the callback.
|
||||
* @param callback Callback method attached to T for the event.
|
||||
*/
|
||||
template<class T>
|
||||
void removeListener(
|
||||
T *instance,
|
||||
void (T::*callback)(A... args)
|
||||
) {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
auto listener = static_cast<EventListener<T,A...>*>(*it);
|
||||
|
||||
if(listener->instance != instance || listener->callback != callback) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
this->listeners.erase(it);
|
||||
delete listener;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the event and emits to all of the listeners.
|
||||
*
|
||||
* @param args Arguments for this event to pass to the listeners.
|
||||
*/
|
||||
void invoke(A... args) {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
(*it)->invoke(args...);
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes the event instance. Will also destroy all of the event
|
||||
* listeners.
|
||||
*/
|
||||
~Event() {
|
||||
auto it = this->listeners.begin();
|
||||
while(it != this->listeners.end()) {
|
||||
delete *it;
|
||||
++it;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
@ -21,7 +21,7 @@ namespace Dawn {
|
||||
|
||||
class IDawnGame {
|
||||
public:
|
||||
std::shared_ptr<Scene> scene;
|
||||
Scene *scene;
|
||||
|
||||
/**
|
||||
* Initialize the game. This is performed by the host at a time that is
|
||||
|
@ -1,92 +1,90 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
/** Implies the host initialized successfully */
|
||||
#define DAWN_HOST_INIT_RESULT_SUCCESS 0
|
||||
|
||||
/** Implies that the update was successful, and the loop should continue */
|
||||
#define DAWN_HOST_UPDATE_RESULT_SUCCESS 0
|
||||
/** Implies that the update was successful, but the loop should not continue */
|
||||
#define DAWN_HOST_UPDATE_RESULT_EXIT 1
|
||||
|
||||
/** Implies that the host started successfully */
|
||||
#define DAWN_HOST_START_RESULT_SUCCESS 0
|
||||
/** Implies that the host started successfully, and then finished everything */
|
||||
#define DAWN_HOST_START_RESULT_EXIT_SUCCESS 1
|
||||
|
||||
namespace Dawn {
|
||||
/**
|
||||
* 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
|
||||
* the window handle during the hosts' session, so that it can destroy it
|
||||
* safely when the host is unloaded.
|
||||
*/
|
||||
class DawnHostData;
|
||||
|
||||
class DawnHost :
|
||||
public std::enable_shared_from_this<DawnHost>
|
||||
{
|
||||
public:
|
||||
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
|
||||
* system. For example, Windows can support both GLFW+GLAD or SDL and may
|
||||
* opt to invoke a DawnHost for either of these scenarios.
|
||||
*/
|
||||
DawnHost();
|
||||
|
||||
/**
|
||||
* Request to initialize the host. Hosts can initialize themselves pretty
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* virtual and is up to the main caller to know how this start method
|
||||
* 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.
|
||||
*/
|
||||
virtual int32_t start(DawnGame &game);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return A status code, refer to DAWN_HOST_UPDATE_RESULT_{} definitions.
|
||||
*/
|
||||
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,
|
||||
* but before the parent program has requested memory freeing.
|
||||
*
|
||||
* @param game Game instance that this host is running for.
|
||||
*/
|
||||
void unload(DawnGame &game);
|
||||
|
||||
/**
|
||||
* Destroy (and unload) all of the DawnHost data from memory.
|
||||
*/
|
||||
~DawnHost();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
/** Implies the host initialized successfully */
|
||||
#define DAWN_HOST_INIT_RESULT_SUCCESS 0
|
||||
|
||||
/** Implies that the update was successful, and the loop should continue */
|
||||
#define DAWN_HOST_UPDATE_RESULT_SUCCESS 0
|
||||
/** Implies that the update was successful, but the loop should not continue */
|
||||
#define DAWN_HOST_UPDATE_RESULT_EXIT 1
|
||||
|
||||
/** Implies that the host started successfully */
|
||||
#define DAWN_HOST_START_RESULT_SUCCESS 0
|
||||
/** Implies that the host started successfully, and then finished everything */
|
||||
#define DAWN_HOST_START_RESULT_EXIT_SUCCESS 1
|
||||
|
||||
namespace Dawn {
|
||||
/**
|
||||
* 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
|
||||
* the window handle during the hosts' session, so that it can destroy it
|
||||
* safely when the host is unloaded.
|
||||
*/
|
||||
class DawnHostData;
|
||||
|
||||
class DawnHost {
|
||||
public:
|
||||
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
|
||||
* system. For example, Windows can support both GLFW+GLAD or SDL and may
|
||||
* opt to invoke a DawnHost for either of these scenarios.
|
||||
*/
|
||||
DawnHost();
|
||||
|
||||
/**
|
||||
* Request to initialize the host. Hosts can initialize themselves pretty
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* virtual and is up to the main caller to know how this start method
|
||||
* 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.
|
||||
*/
|
||||
virtual int32_t start(DawnGame *game);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return A status code, refer to DAWN_HOST_UPDATE_RESULT_{} definitions.
|
||||
*/
|
||||
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,
|
||||
* but before the parent program has requested memory freeing.
|
||||
*
|
||||
* @param game Game instance that this host is running for.
|
||||
*/
|
||||
void unload(DawnGame *game);
|
||||
|
||||
/**
|
||||
* Destroy (and unload) all of the DawnHost data from memory.
|
||||
*/
|
||||
~DawnHost();
|
||||
};
|
||||
}
|
@ -1,161 +1,163 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
typedef int_fast16_t inputbind_t;
|
||||
|
||||
template<typename T>
|
||||
class IInputManager {
|
||||
protected:
|
||||
std::map<inputbind_t, std::vector<T>> binds;
|
||||
std::map<inputbind_t, float_t> valuesLeft;
|
||||
std::map<inputbind_t, float_t> valuesRight;
|
||||
bool_t currentIsLeft = true;
|
||||
|
||||
/**
|
||||
* Method to be overwritten by the platform, reads a RAW input value from
|
||||
* the pad/input device directly.
|
||||
*
|
||||
* @param axis Axis to get the value of.
|
||||
* @return The current input value (between 0 and 1).
|
||||
*/
|
||||
virtual float_t getInputValue(T axis) = 0;
|
||||
|
||||
public:
|
||||
DawnGame &game;
|
||||
|
||||
IInputManager(DawnGame &game) : game(game) {}
|
||||
|
||||
/**
|
||||
* Binds an axis to a bind.
|
||||
*
|
||||
* @param bind Bind to bind the axis to.
|
||||
* @param axis Axis to use for this bind.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void unbind(inputbind_t bind) {
|
||||
this->binds[bind].clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind all values, all of them.
|
||||
*/
|
||||
void unbindAll() {
|
||||
this->binds.clear();
|
||||
this->values.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current bind value.
|
||||
*
|
||||
* @param bind Bind to get the value of.
|
||||
* @return The current input state (between 0 and 1).
|
||||
*/
|
||||
float_t getValue(inputbind_t bind) {
|
||||
if(this->currentIsLeft) {
|
||||
auto exist = this->valuesLeft.find(bind);
|
||||
return exist == this->valuesLeft.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 value of the bind, last frame.
|
||||
*/
|
||||
float_t getValueLastUpdate(inputbind_t bind) {
|
||||
if(this->currentIsLeft) {
|
||||
auto exist = this->valuesRight.find(bind);
|
||||
return exist == this->valuesRight.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).
|
||||
*
|
||||
* @param bind Bind to check if pressed.
|
||||
* @return True if value is non-zero, or false for zero.
|
||||
*/
|
||||
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).
|
||||
*
|
||||
* @param bind Bind to check if pressed.
|
||||
* @return True if down this frame and not down last frame.
|
||||
*/
|
||||
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).
|
||||
*
|
||||
* @param bind Bind to check if released.
|
||||
* @return True if up this frame, and down last frame.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void update() {
|
||||
auto it = this->binds.begin();
|
||||
this->currentIsLeft = !this->currentIsLeft;
|
||||
|
||||
// For each bind...
|
||||
while(it != this->binds.end()) {
|
||||
float_t value = 0.0f;
|
||||
|
||||
// For each input axis...
|
||||
auto bindIt = it->second.begin();
|
||||
while(bindIt != it->second.end()) {
|
||||
// Get value and make the new max.
|
||||
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;
|
||||
} else {
|
||||
this->valuesRight[it->first] = value;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// TODO: trigger events
|
||||
}
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
typedef int_fast16_t inputbind_t;
|
||||
|
||||
template<typename T>
|
||||
class IInputManager {
|
||||
protected:
|
||||
std::map<inputbind_t, std::vector<T>> binds;
|
||||
std::map<inputbind_t, float_t> valuesLeft;
|
||||
std::map<inputbind_t, float_t> valuesRight;
|
||||
bool_t currentIsLeft = true;
|
||||
|
||||
/**
|
||||
* Method to be overwritten by the platform, reads a RAW input value from
|
||||
* the pad/input device directly.
|
||||
*
|
||||
* @param axis Axis to get the value of.
|
||||
* @return The current input value (between 0 and 1).
|
||||
*/
|
||||
virtual float_t getInputValue(T axis) = 0;
|
||||
|
||||
public:
|
||||
DawnGame *game;
|
||||
|
||||
IInputManager(DawnGame *game) {
|
||||
this->game = game;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binds an axis to a bind.
|
||||
*
|
||||
* @param bind Bind to bind the axis to.
|
||||
* @param axis Axis to use for this bind.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void unbind(inputbind_t bind) {
|
||||
this->binds[bind].clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Unbind all values, all of them.
|
||||
*/
|
||||
void unbindAll() {
|
||||
this->binds.clear();
|
||||
this->values.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current bind value.
|
||||
*
|
||||
* @param bind Bind to get the value of.
|
||||
* @return The current input state (between 0 and 1).
|
||||
*/
|
||||
float_t getValue(inputbind_t bind) {
|
||||
if(this->currentIsLeft) {
|
||||
auto exist = this->valuesLeft.find(bind);
|
||||
return exist == this->valuesLeft.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 value of the bind, last frame.
|
||||
*/
|
||||
float_t getValueLastUpdate(inputbind_t bind) {
|
||||
if(this->currentIsLeft) {
|
||||
auto exist = this->valuesRight.find(bind);
|
||||
return exist == this->valuesRight.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).
|
||||
*
|
||||
* @param bind Bind to check if pressed.
|
||||
* @return True if value is non-zero, or false for zero.
|
||||
*/
|
||||
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).
|
||||
*
|
||||
* @param bind Bind to check if pressed.
|
||||
* @return True if down this frame and not down last frame.
|
||||
*/
|
||||
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).
|
||||
*
|
||||
* @param bind Bind to check if released.
|
||||
* @return True if up this frame, and down last frame.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
void update() {
|
||||
auto it = this->binds.begin();
|
||||
this->currentIsLeft = !this->currentIsLeft;
|
||||
|
||||
// For each bind...
|
||||
while(it != this->binds.end()) {
|
||||
float_t value = 0.0f;
|
||||
|
||||
// For each input axis...
|
||||
auto bindIt = it->second.begin();
|
||||
while(bindIt != it->second.end()) {
|
||||
// Get value and make the new max.
|
||||
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;
|
||||
} else {
|
||||
this->valuesRight[it->first] = value;
|
||||
}
|
||||
++it;
|
||||
}
|
||||
|
||||
// TODO: trigger events
|
||||
}
|
||||
};
|
||||
}
|
@ -1,40 +1,42 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Scene::Scene(DawnGame &game) : game(game) {
|
||||
this->nextId = 0;
|
||||
}
|
||||
|
||||
void Scene::update() {
|
||||
// Finsh adding scene items that were trying to add from the last frame.
|
||||
auto it = this->itemsNotInitialized.begin();
|
||||
while(it != this->itemsNotInitialized.end()) {
|
||||
this->items[it->first] = it->second;
|
||||
it->second->init();
|
||||
++it;
|
||||
}
|
||||
this->itemsNotInitialized.clear();
|
||||
|
||||
// TODO: Cleanup old scene items
|
||||
|
||||
// TODO: Tick scene items(?)
|
||||
this->eventSceneUpdate.invoke();
|
||||
if(!this->game.timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke();
|
||||
}
|
||||
|
||||
std::shared_ptr<SceneItem> Scene::createSceneItem() {
|
||||
sceneitemid_t id = this->nextId++;
|
||||
auto item = std::make_shared<SceneItem>(*this, id);
|
||||
this->itemsNotInitialized[id] = item;
|
||||
return item;
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Scene::Scene(DawnGame *game) {
|
||||
this->game = game;
|
||||
this->nextId = 0;
|
||||
}
|
||||
|
||||
void Scene::update() {
|
||||
// Finsh adding scene items that were trying to add from the last frame.
|
||||
auto it = this->itemsNotInitialized.begin();
|
||||
while(it != this->itemsNotInitialized.end()) {
|
||||
this->items[it->first] = it->second;
|
||||
it->second->init();
|
||||
++it;
|
||||
}
|
||||
this->itemsNotInitialized.clear();
|
||||
|
||||
// TODO: Cleanup old scene items
|
||||
|
||||
// TODO: Tick scene items(?)
|
||||
this->eventSceneUpdate.invoke();
|
||||
if(!this->game->timeManager.isPaused) this->eventSceneUnpausedUpdate.invoke();
|
||||
}
|
||||
|
||||
SceneItem * Scene::createSceneItem() {
|
||||
sceneitemid_t id = this->nextId++;
|
||||
auto item = new SceneItem(this, id);
|
||||
this->itemsNotInitialized[id] = item;
|
||||
return item;
|
||||
}
|
||||
|
||||
Scene::~Scene() {
|
||||
|
||||
}
|
@ -1,87 +1,87 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SceneItem.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
|
||||
class Scene {
|
||||
private:
|
||||
sceneitemid_t nextId;
|
||||
std::map<sceneitemid_t, std::shared_ptr<SceneItem>> items;
|
||||
std::map<sceneitemid_t, std::shared_ptr<SceneItem>> itemsNotInitialized;
|
||||
|
||||
public:
|
||||
DawnGame &game;
|
||||
Event<> eventSceneUpdate;
|
||||
Event<> eventSceneUnpausedUpdate;
|
||||
|
||||
/**
|
||||
* Construct a new Scene instance.
|
||||
*
|
||||
* @param game Reference to the game that this scene belongs to.
|
||||
*/
|
||||
Scene(DawnGame &game);
|
||||
|
||||
/**
|
||||
* Perform a one frame synchronous tick on the current scene. This may
|
||||
* change in future to be more event-like.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Create a Scene Item object and add to the current scene.
|
||||
*
|
||||
* @return A shared pointer to the created SceneItem.
|
||||
*/
|
||||
std::shared_ptr<SceneItem> createSceneItem();
|
||||
|
||||
/**
|
||||
* Finds an existing component on the scene (Root Level Only) that has a
|
||||
* component matching the given component type. Returns nullptr if no item
|
||||
* with the specified component could be found.
|
||||
*
|
||||
* @tparam Component type to look for.
|
||||
* @return Pointer to the found component (and by extension the item).
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> findComponent() {
|
||||
auto it = this->items.begin();
|
||||
while(it != this->items.end()) {
|
||||
auto component = it->second->getComponent<T>();
|
||||
if(component != nullptr) return component;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all exisitng components on the scene (Root Level Only) that has a
|
||||
* matching component of the given component type.
|
||||
*
|
||||
* @tparam Component type to look for.
|
||||
* @return List of matching compnoents.
|
||||
*/
|
||||
template<class T>
|
||||
std::vector<std::shared_ptr<T>> findComponents() {
|
||||
std::vector<std::shared_ptr<T>> components;
|
||||
auto it = this->items.begin();
|
||||
while(it != this->items.end()) {
|
||||
auto component = it->second->getComponent<T>();
|
||||
if(component != nullptr) components.push_back(component);
|
||||
++it;
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a previously initialized Scene.
|
||||
*/
|
||||
~Scene();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SceneItem.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class DawnGame;
|
||||
|
||||
class Scene {
|
||||
private:
|
||||
sceneitemid_t nextId;
|
||||
std::map<sceneitemid_t, SceneItem*> items;
|
||||
std::map<sceneitemid_t, SceneItem*> itemsNotInitialized;
|
||||
|
||||
public:
|
||||
DawnGame *game;
|
||||
Event<> eventSceneUpdate;
|
||||
Event<> eventSceneUnpausedUpdate;
|
||||
|
||||
/**
|
||||
* Construct a new Scene instance.
|
||||
*
|
||||
* @param game Reference to the game that this scene belongs to.
|
||||
*/
|
||||
Scene(DawnGame *game);
|
||||
|
||||
/**
|
||||
* Perform a one frame synchronous tick on the current scene. This may
|
||||
* change in future to be more event-like.
|
||||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
* Create a Scene Item object and add to the current scene.
|
||||
*
|
||||
* @return A shared pointer to the created SceneItem.
|
||||
*/
|
||||
SceneItem * createSceneItem();
|
||||
|
||||
/**
|
||||
* Finds an existing component on the scene (Root Level Only) that has a
|
||||
* component matching the given component type. Returns nullptr if no item
|
||||
* with the specified component could be found.
|
||||
*
|
||||
* @tparam Component type to look for.
|
||||
* @return Pointer to the found component (and by extension the item).
|
||||
*/
|
||||
template<class T>
|
||||
T * findComponent() {
|
||||
auto it = this->items.begin();
|
||||
while(it != this->items.end()) {
|
||||
auto component = it->second->getComponent<T>();
|
||||
if(component != nullptr) return component;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all exisitng components on the scene (Root Level Only) that has a
|
||||
* matching component of the given component type.
|
||||
*
|
||||
* @tparam Component type to look for.
|
||||
* @return List of matching compnoents.
|
||||
*/
|
||||
template<class T>
|
||||
std::vector<T*> findComponents() {
|
||||
std::vector<T*> components;
|
||||
auto it = this->items.begin();
|
||||
while(it != this->items.end()) {
|
||||
auto component = it->second->getComponent<T>();
|
||||
if(component != nullptr) components.push_back(component);
|
||||
++it;
|
||||
}
|
||||
return components;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys a previously initialized Scene.
|
||||
*/
|
||||
~Scene();
|
||||
};
|
||||
}
|
@ -1,59 +1,57 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItem.hpp"
|
||||
#include "Scene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItem::SceneItem(Scene &scene, sceneitemid_t id) :
|
||||
scene(scene),
|
||||
id(id),
|
||||
transform(*this)
|
||||
{
|
||||
}
|
||||
|
||||
void SceneItem::init() {
|
||||
// Keep checking all components until they have all inited
|
||||
int32_t waitingOn;
|
||||
do {
|
||||
waitingOn = 0;
|
||||
|
||||
// For each component
|
||||
auto it = this->components.begin();
|
||||
while(it != this->components.end()) {
|
||||
// Has this component already inited?
|
||||
if((*it)->hasInitialized) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
// For each dependency.
|
||||
auto deps = (*it)->getDependencies();
|
||||
bool_t waiting = false;
|
||||
auto it2 = deps.begin();
|
||||
while(it2 != deps.end()) {
|
||||
// Has the dep not yet inited?
|
||||
if(!(*it2)->hasInitialized) {
|
||||
waiting = true;
|
||||
break;
|
||||
}
|
||||
++it2;
|
||||
}
|
||||
|
||||
// Are we waiting for a dep?
|
||||
if(waiting) {
|
||||
waitingOn++;
|
||||
} else {
|
||||
(*it)->init();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} while(waitingOn != 0);
|
||||
}
|
||||
|
||||
SceneItem::~SceneItem() {
|
||||
std::cout << "Scene item disposed" << std::endl;
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItem.hpp"
|
||||
#include "Scene.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItem::SceneItem(Scene *scene, sceneitemid_t id) : transform(this) {
|
||||
this->id = id;
|
||||
this->scene = scene;
|
||||
}
|
||||
|
||||
void SceneItem::init() {
|
||||
// Keep checking all components until they have all inited
|
||||
int32_t waitingOn;
|
||||
do {
|
||||
waitingOn = 0;
|
||||
|
||||
// For each component
|
||||
auto it = this->components.begin();
|
||||
while(it != this->components.end()) {
|
||||
// Has this component already inited?
|
||||
if((*it)->hasInitialized) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
|
||||
// For each dependency.
|
||||
auto deps = (*it)->getDependencies();
|
||||
bool_t waiting = false;
|
||||
auto it2 = deps.begin();
|
||||
while(it2 != deps.end()) {
|
||||
// Has the dep not yet inited?
|
||||
if(!(*it2)->hasInitialized) {
|
||||
waiting = true;
|
||||
break;
|
||||
}
|
||||
++it2;
|
||||
}
|
||||
|
||||
// Are we waiting for a dep?
|
||||
if(waiting) {
|
||||
waitingOn++;
|
||||
} else {
|
||||
(*it)->init();
|
||||
}
|
||||
++it;
|
||||
}
|
||||
} while(waitingOn != 0);
|
||||
}
|
||||
|
||||
SceneItem::~SceneItem() {
|
||||
std::cout << "Scene item disposed" << std::endl;
|
||||
}
|
@ -1,117 +1,117 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SceneItemComponent.hpp"
|
||||
#include "display/Transform.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef int32_t sceneitemid_t;
|
||||
|
||||
class Scene;
|
||||
|
||||
class SceneItem {
|
||||
private:
|
||||
std::vector<std::shared_ptr<SceneItemComponent>> components;
|
||||
|
||||
public:
|
||||
Scene &scene;
|
||||
sceneitemid_t id;
|
||||
Transform transform;
|
||||
|
||||
/**
|
||||
* Constructor for a SceneItem. Scene Items should only be called and
|
||||
* initialized by the scene itself.
|
||||
*
|
||||
* @param scene Weak pointer to the Scene that this SceneItem belongs to.
|
||||
* @param id Scene Item ID that the Scene assigned this SceneItem.
|
||||
*/
|
||||
SceneItem(Scene &scene, sceneitemid_t id);
|
||||
|
||||
/**
|
||||
* Called by the Scene the frame after we were constructed so we can begin
|
||||
* existing.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* the entire SceneItem lifecycle and listen for added callbacks.
|
||||
*
|
||||
* @tparam T Type of component being added to this scene item.
|
||||
* @return A shared pointer to the newly added component.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> addComponent() {
|
||||
auto component = std::make_shared<T>(*this);
|
||||
this->components.push_back(component);
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a component attached to this SceneItem. This method will return
|
||||
* either a shared pointer to the component, or nullptr if the item does
|
||||
* not have the queried component.
|
||||
*
|
||||
* @tparam T Type of component to be fetched.
|
||||
* @return A shared pointer to the component, or nullptr if not found.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> getComponent() {
|
||||
auto it = this->components.begin();
|
||||
while(it != this->components.end()) {
|
||||
auto castedAs = std::dynamic_pointer_cast<T>(*it);
|
||||
if(castedAs != nullptr) return castedAs;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a (direct) child of this component that has a matching component.
|
||||
*
|
||||
* @tparam T Component to find child of.
|
||||
* @return Pointer to the child, or nullptr if not found.
|
||||
*/
|
||||
template<class T>
|
||||
std::shared_ptr<T> findChild() {
|
||||
auto it = this->transform.children.begin();
|
||||
while(it != this->transform.children.end()) {
|
||||
auto child = (*it)->item.getComponent<T>();
|
||||
if(child != nullptr) return child;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all (direct) children of this component that match the queried
|
||||
* component.
|
||||
*
|
||||
* @tparam T Component to find children for.
|
||||
* @return Array of pointers to matching children.
|
||||
*/
|
||||
template<class T>
|
||||
std::vector<std::shared_ptr<T>> findChildren() {
|
||||
auto it = this->transform.children.begin();
|
||||
std::vector<std::shared_ptr<T>> children;
|
||||
while(it != this->transform.children.end()) {
|
||||
auto child = (*it)->item.getComponent<T>();
|
||||
if(child != nullptr) children.push_back(child);
|
||||
++it;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy this SceneItem.
|
||||
*/
|
||||
~SceneItem();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "SceneItemComponent.hpp"
|
||||
#include "display/Transform.hpp"
|
||||
#include "event/Event.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
typedef int32_t sceneitemid_t;
|
||||
|
||||
class Scene;
|
||||
|
||||
class SceneItem {
|
||||
private:
|
||||
std::vector<SceneItemComponent*> components;
|
||||
|
||||
public:
|
||||
Scene *scene;
|
||||
sceneitemid_t id;
|
||||
Transform transform;
|
||||
|
||||
/**
|
||||
* Constructor for a SceneItem. Scene Items should only be called and
|
||||
* initialized by the scene itself.
|
||||
*
|
||||
* @param scene Weak pointer to the Scene that this SceneItem belongs to.
|
||||
* @param id Scene Item ID that the Scene assigned this SceneItem.
|
||||
*/
|
||||
SceneItem(Scene *scene, sceneitemid_t id);
|
||||
|
||||
/**
|
||||
* Called by the Scene the frame after we were constructed so we can begin
|
||||
* existing.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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
|
||||
* the entire SceneItem lifecycle and listen for added callbacks.
|
||||
*
|
||||
* @tparam T Type of component being added to this scene item.
|
||||
* @return A shared pointer to the newly added component.
|
||||
*/
|
||||
template<class T>
|
||||
T * addComponent() {
|
||||
auto component = new T(this);
|
||||
this->components.push_back(component);
|
||||
return component;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a component attached to this SceneItem. This method will return
|
||||
* either a shared pointer to the component, or nullptr if the item does
|
||||
* not have the queried component.
|
||||
*
|
||||
* @tparam T Type of component to be fetched.
|
||||
* @return A shared pointer to the component, or nullptr if not found.
|
||||
*/
|
||||
template<class T>
|
||||
T * getComponent() {
|
||||
auto it = this->components.begin();
|
||||
while(it != this->components.end()) {
|
||||
T *castedAs = dynamic_cast<T*>(*it);
|
||||
if(castedAs != nullptr) return castedAs;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a (direct) child of this component that has a matching component.
|
||||
*
|
||||
* @tparam T Component to find child of.
|
||||
* @return Pointer to the child, or nullptr if not found.
|
||||
*/
|
||||
template<class T>
|
||||
T * findChild() {
|
||||
auto it = this->transform.children.begin();
|
||||
while(it != this->transform.children.end()) {
|
||||
auto child = (*it)->item->getComponent<T>();
|
||||
if(child != nullptr) return child;
|
||||
++it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds all (direct) children of this component that match the queried
|
||||
* component.
|
||||
*
|
||||
* @tparam T Component to find children for.
|
||||
* @return Array of pointers to matching children.
|
||||
*/
|
||||
template<class T>
|
||||
std::vector<T*> findChildren() {
|
||||
auto it = this->transform.children.begin();
|
||||
std::vector<T*> children;
|
||||
while(it != this->transform.children.end()) {
|
||||
auto child = (*it)->item->getComponent<T>();
|
||||
if(child != nullptr) children.push_back(child);
|
||||
++it;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy this SceneItem.
|
||||
*/
|
||||
~SceneItem();
|
||||
};
|
||||
}
|
@ -1,42 +1,41 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItemComponent.hpp"
|
||||
#include "SceneItem.hpp"
|
||||
#include "Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItemComponent::SceneItemComponent(SceneItem &item) :
|
||||
item(item),
|
||||
transform(item.transform)
|
||||
{
|
||||
}
|
||||
|
||||
void SceneItemComponent::init() {
|
||||
this->onStart();
|
||||
this->hasInitialized = true;
|
||||
}
|
||||
|
||||
std::vector<SceneItemComponent*> SceneItemComponent::getDependencies() {
|
||||
return std::vector<SceneItemComponent*>();
|
||||
}
|
||||
|
||||
Scene & SceneItemComponent::getScene() {
|
||||
return this->item.scene;
|
||||
}
|
||||
|
||||
DawnGame & SceneItemComponent::getGame() {
|
||||
return this->item.scene.game;
|
||||
}
|
||||
|
||||
void SceneItemComponent::onStart() {
|
||||
|
||||
}
|
||||
|
||||
SceneItemComponent::~SceneItemComponent() {
|
||||
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "SceneItemComponent.hpp"
|
||||
#include "SceneItem.hpp"
|
||||
#include "Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
SceneItemComponent::SceneItemComponent(SceneItem *item) {
|
||||
this->item = item;
|
||||
this->transform = &item->transform;
|
||||
}
|
||||
|
||||
void SceneItemComponent::init() {
|
||||
this->onStart();
|
||||
this->hasInitialized = true;
|
||||
}
|
||||
|
||||
std::vector<SceneItemComponent*> SceneItemComponent::getDependencies() {
|
||||
return std::vector<SceneItemComponent*>();
|
||||
}
|
||||
|
||||
Scene * SceneItemComponent::getScene() {
|
||||
return this->item->scene;
|
||||
}
|
||||
|
||||
DawnGame * SceneItemComponent::getGame() {
|
||||
return this->item->scene->game;
|
||||
}
|
||||
|
||||
void SceneItemComponent::onStart() {
|
||||
|
||||
}
|
||||
|
||||
SceneItemComponent::~SceneItemComponent() {
|
||||
|
||||
}
|
@ -1,66 +1,66 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/Transform.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
class Scene;
|
||||
class DawnGame;
|
||||
|
||||
class SceneItemComponent {
|
||||
public:
|
||||
SceneItem &item;
|
||||
Transform &transform;
|
||||
bool_t hasInitialized = false;
|
||||
|
||||
/**
|
||||
* Constructs a new SceneItemComponent. Components are attached to
|
||||
* SceneItems and will be individual responsibility components, and must
|
||||
* communicate to other items/components using methods and events.
|
||||
*
|
||||
* @param item Scene Item thsi component belongs to.
|
||||
*/
|
||||
SceneItemComponent(SceneItem &item);
|
||||
|
||||
/**
|
||||
* Requested on the first frame that the parent scene item has become
|
||||
* active, after all of my dependencies are ready.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Optionally return all dependencies for this component to wait for init
|
||||
* for before the component will be initialized.
|
||||
*
|
||||
* @return Array of dependencies.
|
||||
*/
|
||||
virtual std::vector<SceneItemComponent*> getDependencies();
|
||||
|
||||
/**
|
||||
* Shorthand to return the scene that this component's item belongs to.
|
||||
* @return The current scene.
|
||||
*/
|
||||
Scene & getScene();
|
||||
|
||||
/**
|
||||
* Shorthand to return the game that this scene belongs to.
|
||||
* @return The current game.
|
||||
*/
|
||||
DawnGame & getGame();
|
||||
|
||||
/**
|
||||
* Same as init, but intended for your subclass to override.
|
||||
*/
|
||||
virtual void onStart();
|
||||
|
||||
/**
|
||||
* Cleanup the SceneItemComponent.
|
||||
*/
|
||||
virtual ~SceneItemComponent();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "dawnlibs.hpp"
|
||||
#include "display/Transform.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class SceneItem;
|
||||
class Scene;
|
||||
class DawnGame;
|
||||
|
||||
class SceneItemComponent {
|
||||
public:
|
||||
SceneItem *item;
|
||||
Transform *transform;
|
||||
bool_t hasInitialized = false;
|
||||
|
||||
/**
|
||||
* Constructs a new SceneItemComponent. Components are attached to
|
||||
* SceneItems and will be individual responsibility components, and must
|
||||
* communicate to other items/components using methods and events.
|
||||
*
|
||||
* @param item Scene Item thsi component belongs to.
|
||||
*/
|
||||
SceneItemComponent(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Requested on the first frame that the parent scene item has become
|
||||
* active, after all of my dependencies are ready.
|
||||
*/
|
||||
void init();
|
||||
|
||||
/**
|
||||
* Optionally return all dependencies for this component to wait for init
|
||||
* for before the component will be initialized.
|
||||
*
|
||||
* @return Array of dependencies.
|
||||
*/
|
||||
virtual std::vector<SceneItemComponent*> getDependencies();
|
||||
|
||||
/**
|
||||
* Shorthand to return the scene that this component's item belongs to.
|
||||
* @return The current scene.
|
||||
*/
|
||||
Scene * getScene();
|
||||
|
||||
/**
|
||||
* Shorthand to return the game that this scene belongs to.
|
||||
* @return The current game.
|
||||
*/
|
||||
DawnGame * getGame();
|
||||
|
||||
/**
|
||||
* Same as init, but intended for your subclass to override.
|
||||
*/
|
||||
virtual void onStart();
|
||||
|
||||
/**
|
||||
* Cleanup the SceneItemComponent.
|
||||
*/
|
||||
virtual ~SceneItemComponent();
|
||||
};
|
||||
}
|
@ -1,80 +1,80 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Camera::Camera(SceneItem &item) :
|
||||
SceneItemComponent(item)
|
||||
{
|
||||
this->getRenderTarget().eventRenderTargetResized.addListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
}
|
||||
|
||||
void Camera::updateProjection() {
|
||||
switch(this->type) {
|
||||
case CAMERA_TYPE_ORTHONOGRAPHIC:
|
||||
this->projection = glm::ortho(
|
||||
this->orthoLeft,
|
||||
this->orthoRight,
|
||||
this->orthoBottom,
|
||||
this->orthoTop,
|
||||
this->clipNear,
|
||||
this->clipFar
|
||||
);
|
||||
break;
|
||||
|
||||
case CAMERA_TYPE_PERSPECTIVE:
|
||||
this->projection = glm::perspective(
|
||||
this->fov,
|
||||
this->getAspect(),
|
||||
this->clipNear,
|
||||
this->clipFar
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RenderTarget & Camera::getRenderTarget() {
|
||||
if(this->target == nullptr) {
|
||||
return this->getGame().renderManager.getBackBuffer();
|
||||
}
|
||||
return *this->target;
|
||||
}
|
||||
|
||||
void Camera::setRenderTarget(std::shared_ptr<RenderTarget> renderTarget) {
|
||||
if(renderTarget == this->target) return;
|
||||
this->getRenderTarget().eventRenderTargetResized.removeListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
this->target = renderTarget;
|
||||
this->getRenderTarget().eventRenderTargetResized.addListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
float_t Camera::getAspect() {
|
||||
RenderTarget &target = this->getRenderTarget();
|
||||
return target.getWidth() / target.getHeight();
|
||||
}
|
||||
|
||||
void Camera::onStart() {
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
void Camera::onRenderTargetResize(RenderTarget &target, float_t w, float_t h) {
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
Camera::~Camera() {
|
||||
this->getRenderTarget().eventRenderTargetResized.removeListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Camera.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Camera::Camera(SceneItem *item) :
|
||||
SceneItemComponent(item)
|
||||
{
|
||||
this->getRenderTarget()->eventRenderTargetResized.addListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
}
|
||||
|
||||
void Camera::updateProjection() {
|
||||
switch(this->type) {
|
||||
case CAMERA_TYPE_ORTHONOGRAPHIC:
|
||||
this->projection = glm::ortho(
|
||||
this->orthoLeft,
|
||||
this->orthoRight,
|
||||
this->orthoBottom,
|
||||
this->orthoTop,
|
||||
this->clipNear,
|
||||
this->clipFar
|
||||
);
|
||||
break;
|
||||
|
||||
case CAMERA_TYPE_PERSPECTIVE:
|
||||
this->projection = glm::perspective(
|
||||
this->fov,
|
||||
this->getAspect(),
|
||||
this->clipNear,
|
||||
this->clipFar
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
RenderTarget * Camera::getRenderTarget() {
|
||||
if(this->target == nullptr) {
|
||||
return this->getGame()->renderManager.getBackBuffer();
|
||||
}
|
||||
return this->target;
|
||||
}
|
||||
|
||||
void Camera::setRenderTarget(RenderTarget *renderTarget) {
|
||||
if(renderTarget == this->target) return;
|
||||
this->getRenderTarget()->eventRenderTargetResized.removeListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
this->target = renderTarget;
|
||||
this->getRenderTarget()->eventRenderTargetResized.addListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
float_t Camera::getAspect() {
|
||||
RenderTarget *target = this->getRenderTarget();
|
||||
return target->getWidth() / target->getHeight();
|
||||
}
|
||||
|
||||
void Camera::onStart() {
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
void Camera::onRenderTargetResize(RenderTarget *target, float_t w, float_t h) {
|
||||
this->updateProjection();
|
||||
}
|
||||
|
||||
Camera::~Camera() {
|
||||
this->getRenderTarget()->eventRenderTargetResized.removeListener(
|
||||
this, &Camera::onRenderTargetResize
|
||||
);
|
||||
}
|
@ -1,83 +1,83 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum CameraType {
|
||||
CAMERA_TYPE_ORTHONOGRAPHIC,
|
||||
CAMERA_TYPE_PERSPECTIVE
|
||||
};
|
||||
|
||||
class Camera : public SceneItemComponent {
|
||||
protected:
|
||||
std::shared_ptr<RenderTarget> target = nullptr;
|
||||
|
||||
void onRenderTargetResize(RenderTarget &target, float_t w, float_t h);
|
||||
|
||||
public:
|
||||
glm::mat4 projection;
|
||||
|
||||
// Perspective
|
||||
enum CameraType type = CAMERA_TYPE_PERSPECTIVE;
|
||||
float_t fov = 0.785398f;// 45 degrees
|
||||
|
||||
// Ortho
|
||||
float_t orthoLeft = 0.0f;
|
||||
float_t orthoRight = 1.0f;
|
||||
float_t orthoBottom = 0.0f;
|
||||
float_t orthoTop = 1.0f;
|
||||
|
||||
// Shared
|
||||
float_t clipNear = 0.001f;
|
||||
float_t clipFar = 100.0f;
|
||||
|
||||
/**
|
||||
* Create a new Camera Component.
|
||||
*
|
||||
* @param item SceneItem that this component belongs to.
|
||||
*/
|
||||
Camera(SceneItem &item);
|
||||
|
||||
/**
|
||||
* Updates the projection matrix.
|
||||
*/
|
||||
void updateProjection();
|
||||
|
||||
/**
|
||||
* Returns the intended render target for this camera to render to, will
|
||||
* automatically revert to the back buffer if no frame buffer is provided.
|
||||
*
|
||||
* @return The target render target framebuffer.
|
||||
*/
|
||||
RenderTarget & getRenderTarget();
|
||||
|
||||
/**
|
||||
* Updates the render target for the camera to use.
|
||||
*
|
||||
* @param renderTarget Render target for this camera to draw to.
|
||||
*/
|
||||
void setRenderTarget(std::shared_ptr<RenderTarget> renderTarget);
|
||||
|
||||
/**
|
||||
* Returs the aspect ratio of the camera.
|
||||
*
|
||||
* @return The aspect ratio of the camera.
|
||||
*/
|
||||
float_t getAspect();
|
||||
|
||||
/**
|
||||
* Event triggered by the scene item when the item is added to the scene.
|
||||
*/
|
||||
void onStart() override;
|
||||
|
||||
/**
|
||||
* Disposes a previously initialized camera.
|
||||
*/
|
||||
~Camera();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum CameraType {
|
||||
CAMERA_TYPE_ORTHONOGRAPHIC,
|
||||
CAMERA_TYPE_PERSPECTIVE
|
||||
};
|
||||
|
||||
class Camera : public SceneItemComponent {
|
||||
protected:
|
||||
RenderTarget *target = nullptr;
|
||||
|
||||
void onRenderTargetResize(RenderTarget *target, float_t w, float_t h);
|
||||
|
||||
public:
|
||||
glm::mat4 projection;
|
||||
|
||||
// Perspective
|
||||
enum CameraType type = CAMERA_TYPE_PERSPECTIVE;
|
||||
float_t fov = 0.785398f;// 45 degrees
|
||||
|
||||
// Ortho
|
||||
float_t orthoLeft = 0.0f;
|
||||
float_t orthoRight = 1.0f;
|
||||
float_t orthoBottom = 0.0f;
|
||||
float_t orthoTop = 1.0f;
|
||||
|
||||
// Shared
|
||||
float_t clipNear = 0.001f;
|
||||
float_t clipFar = 100.0f;
|
||||
|
||||
/**
|
||||
* Create a new Camera Component.
|
||||
*
|
||||
* @param item SceneItem that this component belongs to.
|
||||
*/
|
||||
Camera(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Updates the projection matrix.
|
||||
*/
|
||||
void updateProjection();
|
||||
|
||||
/**
|
||||
* Returns the intended render target for this camera to render to, will
|
||||
* automatically revert to the back buffer if no frame buffer is provided.
|
||||
*
|
||||
* @return The target render target framebuffer.
|
||||
*/
|
||||
RenderTarget * getRenderTarget();
|
||||
|
||||
/**
|
||||
* Updates the render target for the camera to use.
|
||||
*
|
||||
* @param renderTarget Render target for this camera to draw to.
|
||||
*/
|
||||
void setRenderTarget(RenderTarget *renderTarget);
|
||||
|
||||
/**
|
||||
* Returs the aspect ratio of the camera.
|
||||
*
|
||||
* @return The aspect ratio of the camera.
|
||||
*/
|
||||
float_t getAspect();
|
||||
|
||||
/**
|
||||
* Event triggered by the scene item when the item is added to the scene.
|
||||
*/
|
||||
void onStart() override;
|
||||
|
||||
/**
|
||||
* Disposes a previously initialized camera.
|
||||
*/
|
||||
~Camera();
|
||||
};
|
||||
}
|
@ -1,72 +1,70 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Material.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Material::Material(SceneItem &item) :
|
||||
SceneItemComponent(item),
|
||||
shader(item.scene.game.renderManager.getDefaultShader())
|
||||
{
|
||||
this->updateShaderParameters();
|
||||
}
|
||||
|
||||
void Material::updateShaderParameters() {
|
||||
this->colorValues.clear();
|
||||
this->boolValues.clear();
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
void Material::setShaderParameters() {
|
||||
auto it = this->parameters.begin();
|
||||
while(it != this->parameters.end()) {
|
||||
switch(it->second) {
|
||||
case SHADER_PARAMETER_TYPE_COLOR:
|
||||
this->shader->setColor(it->first, this->colorValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_MATRIX:
|
||||
this->shader->setMatrix(it->first, this->matrixValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_BOOLEAN:
|
||||
this->shader->setBoolean(it->first, this->boolValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_VECTOR3:
|
||||
this->shader->setVector3(it->first, this->vec3Values[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_TEXTURE:
|
||||
this->shader->setTexture(it->first, this->textureValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_FLOAT:
|
||||
this->shader->setFloat(it->first, this->floatValues[it->first]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "An unsupported or invalid shader parameter type was supplied.";
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<Shader> Material::getShader() {
|
||||
return this->shader;
|
||||
}
|
||||
|
||||
void Material::setShader(std::shared_ptr<Shader> shader) {
|
||||
this->shader = shader;
|
||||
this->updateShaderParameters();
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "Material.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
Material::Material(SceneItem *item) : SceneItemComponent(item) {
|
||||
this->shader = item->scene->game->renderManager.getDefaultShader();
|
||||
this->updateShaderParameters();
|
||||
}
|
||||
|
||||
void Material::updateShaderParameters() {
|
||||
this->colorValues.clear();
|
||||
this->boolValues.clear();
|
||||
|
||||
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.
|
||||
}
|
||||
|
||||
void Material::setShaderParameters() {
|
||||
auto it = this->parameters.begin();
|
||||
while(it != this->parameters.end()) {
|
||||
switch(it->second) {
|
||||
case SHADER_PARAMETER_TYPE_COLOR:
|
||||
this->shader->setColor(it->first, this->colorValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_MATRIX:
|
||||
this->shader->setMatrix(it->first, this->matrixValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_BOOLEAN:
|
||||
this->shader->setBoolean(it->first, this->boolValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_VECTOR3:
|
||||
this->shader->setVector3(it->first, this->vec3Values[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_TEXTURE:
|
||||
this->shader->setTexture(it->first, this->textureValues[it->first]);
|
||||
break;
|
||||
|
||||
case SHADER_PARAMETER_TYPE_FLOAT:
|
||||
this->shader->setFloat(it->first, this->floatValues[it->first]);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw "An unsupported or invalid shader parameter type was supplied.";
|
||||
}
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
Shader * Material::getShader() {
|
||||
return this->shader;
|
||||
}
|
||||
|
||||
void Material::setShader(Shader * shader) {
|
||||
this->shader = shader;
|
||||
this->updateShaderParameters();
|
||||
}
|
@ -1,63 +1,63 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Shader;
|
||||
|
||||
class Material : public SceneItemComponent {
|
||||
private:
|
||||
std::shared_ptr<Shader> shader;
|
||||
|
||||
/**
|
||||
* Internal method that will be invoked to go through and update all of
|
||||
* the shader parameters whenever the shader is swapped out.
|
||||
*/
|
||||
void updateShaderParameters();
|
||||
|
||||
public:
|
||||
std::map<shaderparameter_t, enum ShaderParameterType> parameters;
|
||||
std::map<shaderparameter_t, struct Color> colorValues;
|
||||
std::map<shaderparameter_t, bool_t> boolValues;
|
||||
std::map<shaderparameter_t, glm::mat4> matrixValues;
|
||||
std::map<shaderparameter_t, glm::vec3> vec3Values;
|
||||
std::map<shaderparameter_t, Texture*> textureValues;
|
||||
std::map<shaderparameter_t, float_t> floatValues;
|
||||
|
||||
/**
|
||||
* Material component constructor.
|
||||
*
|
||||
* @param item Scene Item this component belongs to.
|
||||
*/
|
||||
Material(SceneItem &item);
|
||||
|
||||
/**
|
||||
* Return the shader this material is currently using.
|
||||
*
|
||||
* @return Shader pointer to the currently bound shader.
|
||||
*/
|
||||
std::shared_ptr<Shader> getShader();
|
||||
|
||||
/**
|
||||
* Sets the shader for the material to use. This will also clear and
|
||||
* update all of the parameters from the shaders' default parameter list.
|
||||
*
|
||||
* @param shader Shader to set.
|
||||
*/
|
||||
void setShader(std::shared_ptr<Shader> shader);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the shader.
|
||||
*
|
||||
* This method assumes that the shader has already been bound.
|
||||
*/
|
||||
void setShaderParameters();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/shader/Shader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class Shader;
|
||||
|
||||
class Material : public SceneItemComponent {
|
||||
private:
|
||||
Shader *shader;
|
||||
|
||||
/**
|
||||
* Internal method that will be invoked to go through and update all of
|
||||
* the shader parameters whenever the shader is swapped out.
|
||||
*/
|
||||
void updateShaderParameters();
|
||||
|
||||
public:
|
||||
std::map<shaderparameter_t, enum ShaderParameterType> parameters;
|
||||
std::map<shaderparameter_t, struct Color> colorValues;
|
||||
std::map<shaderparameter_t, bool_t> boolValues;
|
||||
std::map<shaderparameter_t, glm::mat4> matrixValues;
|
||||
std::map<shaderparameter_t, glm::vec3> vec3Values;
|
||||
std::map<shaderparameter_t, Texture*> textureValues;
|
||||
std::map<shaderparameter_t, float_t> floatValues;
|
||||
|
||||
/**
|
||||
* Material component constructor.
|
||||
*
|
||||
* @param item Scene Item this component belongs to.
|
||||
*/
|
||||
Material(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Return the shader this material is currently using.
|
||||
*
|
||||
* @return Shader pointer to the currently bound shader.
|
||||
*/
|
||||
Shader * getShader();
|
||||
|
||||
/**
|
||||
* Sets the shader for the material to use. This will also clear and
|
||||
* update all of the parameters from the shaders' default parameter list.
|
||||
*
|
||||
* @param shader Shader to set.
|
||||
*/
|
||||
void setShader(Shader * shader);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* the shader.
|
||||
*
|
||||
* This method assumes that the shader has already been bound.
|
||||
*/
|
||||
void setShaderParameters();
|
||||
};
|
||||
}
|
@ -1,14 +1,11 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "MeshRenderer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
MeshRenderer::MeshRenderer(SceneItem &item) :
|
||||
SceneItemComponent(item)
|
||||
{
|
||||
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "MeshRenderer.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
MeshRenderer::MeshRenderer(SceneItem *item) : SceneItemComponent(item) {
|
||||
}
|
@ -1,22 +1,22 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class MeshRenderer : public SceneItemComponent {
|
||||
public:
|
||||
std::shared_ptr<Mesh> mesh = nullptr;
|
||||
|
||||
/**
|
||||
* Constructs a MeshRenderer scene item component.
|
||||
*
|
||||
* @param item Scene Item this mesh renderer belongs to.
|
||||
*/
|
||||
MeshRenderer(SceneItem &item);
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/mesh/Mesh.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class MeshRenderer : public SceneItemComponent {
|
||||
public:
|
||||
Mesh * mesh = nullptr;
|
||||
|
||||
/**
|
||||
* Constructs a MeshRenderer scene item component.
|
||||
*
|
||||
* @param item Scene Item this mesh renderer belongs to.
|
||||
*/
|
||||
MeshRenderer(SceneItem *item);
|
||||
};
|
||||
}
|
@ -1,52 +1,51 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UICanvas.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
std::shared_ptr<UICanvas> UICanvas::createCanvas(std::shared_ptr<Scene> scene) {
|
||||
auto item = scene->createSceneItem();
|
||||
return item->addComponent<UICanvas>();
|
||||
}
|
||||
|
||||
UICanvas::UICanvas(SceneItem &item) : SceneItemComponent(item) {
|
||||
}
|
||||
|
||||
float_t UICanvas::getWidth() {
|
||||
return this->getGame().renderManager.getBackBuffer().getWidth();
|
||||
}
|
||||
|
||||
float_t UICanvas::getHeight() {
|
||||
return this->getGame().renderManager.getBackBuffer().getHeight();
|
||||
}
|
||||
|
||||
void UICanvas::onStart() {
|
||||
std::cout << "Canvas event" << std::endl;
|
||||
this->getGame().renderManager.getBackBuffer()
|
||||
.eventRenderTargetResized.addListener(this, &UICanvas::onBackBufferResize)
|
||||
;
|
||||
}
|
||||
|
||||
void UICanvas::onBackBufferResize(
|
||||
RenderTarget &target,
|
||||
float_t width,
|
||||
float_t height
|
||||
) {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->updatePositions();
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
UICanvas::~UICanvas() {
|
||||
this->getGame().renderManager.getBackBuffer()
|
||||
.eventRenderTargetResized.removeListener(this, &UICanvas::onBackBufferResize)
|
||||
;
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UICanvas.hpp"
|
||||
#include "scene/Scene.hpp"
|
||||
#include "ui/UIComponent.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UICanvas * UICanvas::createCanvas(Scene *scene) {
|
||||
auto item = scene->createSceneItem();
|
||||
return item->addComponent<UICanvas>();
|
||||
}
|
||||
|
||||
UICanvas::UICanvas(SceneItem *item) : SceneItemComponent(item) {
|
||||
}
|
||||
|
||||
float_t UICanvas::getWidth() {
|
||||
return this->getGame()->renderManager.getBackBuffer()->getWidth();
|
||||
}
|
||||
|
||||
float_t UICanvas::getHeight() {
|
||||
return this->getGame()->renderManager.getBackBuffer()->getHeight();
|
||||
}
|
||||
|
||||
void UICanvas::onStart() {
|
||||
this->getGame()->renderManager.getBackBuffer()->eventRenderTargetResized
|
||||
.addListener(this, &UICanvas::onBackBufferResize)
|
||||
;
|
||||
}
|
||||
|
||||
void UICanvas::onBackBufferResize(
|
||||
RenderTarget *target,
|
||||
float_t width,
|
||||
float_t height
|
||||
) {
|
||||
auto it = this->children.begin();
|
||||
while(it != this->children.end()) {
|
||||
(*it)->updatePositions();
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
UICanvas::~UICanvas() {
|
||||
this->getGame()->renderManager.getBackBuffer()->eventRenderTargetResized
|
||||
.removeListener(this, &UICanvas::onBackBufferResize)
|
||||
;
|
||||
}
|
@ -1,52 +1,80 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum UIDrawType {
|
||||
UI_DRAW_TYPE_WORLD_ABSOLUTE,
|
||||
UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE,
|
||||
UI_DRAW_TYPE_CAMERA_OVERLAY
|
||||
};
|
||||
|
||||
class UIComponent;
|
||||
|
||||
class UICanvas : public SceneItemComponent {
|
||||
protected:
|
||||
void onBackBufferResize(
|
||||
RenderTarget &target,
|
||||
float_t width,
|
||||
float_t height
|
||||
);
|
||||
|
||||
public:
|
||||
static std::shared_ptr<UICanvas> createCanvas(
|
||||
std::shared_ptr<Scene> scene
|
||||
);
|
||||
|
||||
//
|
||||
std::vector<std::shared_ptr<UIComponent>> children;
|
||||
UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
|
||||
|
||||
UICanvas(SceneItem &item);
|
||||
|
||||
template<class T>
|
||||
std::shared_ptr<T> addElement() {
|
||||
auto item = std::make_shared<T>(*this);
|
||||
this->children.push_back(item);
|
||||
return item;
|
||||
}
|
||||
|
||||
float_t getWidth();
|
||||
float_t getHeight();
|
||||
|
||||
void onStart() override;
|
||||
|
||||
~UICanvas();
|
||||
};
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "scene/SceneItemComponent.hpp"
|
||||
#include "display/RenderTarget.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
enum UIDrawType {
|
||||
UI_DRAW_TYPE_WORLD_ABSOLUTE,
|
||||
UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE,
|
||||
UI_DRAW_TYPE_CAMERA_OVERLAY
|
||||
};
|
||||
|
||||
class UIComponent;
|
||||
|
||||
class UICanvas : public SceneItemComponent {
|
||||
protected:
|
||||
void onBackBufferResize(
|
||||
RenderTarget *target,
|
||||
float_t width,
|
||||
float_t height
|
||||
);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a UI Canvas Scene Item Element, and attaches it to the provided
|
||||
* scene.
|
||||
*
|
||||
* @param scene Scene to create the UI Canvas for.
|
||||
* @return Created UI Canvas.
|
||||
*/
|
||||
static UICanvas * createCanvas(Scene *scene);
|
||||
|
||||
//
|
||||
std::vector<UIComponent*> children;
|
||||
UIDrawType drawType = UI_DRAW_TYPE_WORLD_CAMERA_RELATIVE;
|
||||
|
||||
/**
|
||||
* Constructs the UI Canvas Scene Item Component.
|
||||
*
|
||||
* @param item Item that this canvas item belongs to.
|
||||
*/
|
||||
UICanvas(SceneItem *item);
|
||||
|
||||
/**
|
||||
* Construct and append a UI item to this UI Canvas.
|
||||
*
|
||||
* @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();
|
||||
};
|
||||
}
|
@ -7,7 +7,7 @@
|
||||
|
||||
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->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;
|
||||
|
||||
shader.setUIColor(COLOR_WHITE);
|
||||
shader.setUIModel(transform);
|
||||
shader.setUITexture(this->texture);
|
||||
shader->setUIColor(COLOR_WHITE);
|
||||
shader->setUIModel(transform);
|
||||
shader->setUITexture(this->texture);
|
||||
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
}
|
||||
|
||||
|
@ -17,12 +17,12 @@ namespace Dawn {
|
||||
glm::vec2 uv1 = glm::vec2(1.0f, 1.0f);
|
||||
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
|
||||
public:
|
||||
Texture *texture;
|
||||
|
||||
UIBorder(UICanvas &canvas);
|
||||
UIBorder(UICanvas *canvas);
|
||||
|
||||
/**
|
||||
* Changes the dimensions of the border.
|
||||
|
@ -7,16 +7,15 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UIComponent::UIComponent(UICanvas &canvas) :
|
||||
canvas(canvas)
|
||||
{
|
||||
UIComponent::UIComponent(UICanvas *canvas) {
|
||||
this->canvas = canvas;
|
||||
}
|
||||
|
||||
void UIComponent::updatePositions() {
|
||||
// X Alignment
|
||||
if(this->alignX == UI_COMPONENT_ALIGN_STRETCH) {
|
||||
if(this->parent == nullptr) {
|
||||
this->width = this->canvas.getWidth();
|
||||
this->width = this->canvas->getWidth();
|
||||
} else {
|
||||
this->width = this->parent->getWidth();
|
||||
}
|
||||
@ -28,7 +27,7 @@ void UIComponent::updatePositions() {
|
||||
} else if(this->alignX == UI_COMPONENT_ALIGN_END) {
|
||||
this->width = this->alignment[0];
|
||||
if(this->parent == nullptr) {
|
||||
this->relativeX = this->canvas.getWidth();
|
||||
this->relativeX = this->canvas->getWidth();
|
||||
} else {
|
||||
this->relativeX = this->parent->getWidth();
|
||||
}
|
||||
@ -37,7 +36,7 @@ void UIComponent::updatePositions() {
|
||||
} else if(this->alignX == UI_COMPONENT_ALIGN_MIDDLE) {
|
||||
this->width = this->alignment[2];
|
||||
if(this->parent == nullptr) {
|
||||
this->relativeX = this->canvas.getWidth();
|
||||
this->relativeX = this->canvas->getWidth();
|
||||
} else {
|
||||
this->relativeX = this->parent->getWidth();
|
||||
}
|
||||
@ -47,7 +46,7 @@ void UIComponent::updatePositions() {
|
||||
// Y Alignment
|
||||
if(this->alignY == UI_COMPONENT_ALIGN_STRETCH) {
|
||||
if(this->parent == nullptr) {
|
||||
this->height = this->canvas.getHeight();
|
||||
this->height = this->canvas->getHeight();
|
||||
} else {
|
||||
this->height = this->parent->getHeight();
|
||||
}
|
||||
@ -59,7 +58,7 @@ void UIComponent::updatePositions() {
|
||||
} else if(this->alignY == UI_COMPONENT_ALIGN_END) {
|
||||
this->height = this->alignment[1];
|
||||
if(this->parent == nullptr) {
|
||||
this->relativeY = this->canvas.getHeight();
|
||||
this->relativeY = this->canvas->getHeight();
|
||||
} else {
|
||||
this->relativeY = this->parent->getHeight();
|
||||
}
|
||||
@ -68,7 +67,7 @@ void UIComponent::updatePositions() {
|
||||
} else if(this->alignY == UI_COMPONENT_ALIGN_MIDDLE) {
|
||||
this->height = this->alignment[3];
|
||||
if(this->parent == nullptr) {
|
||||
this->relativeY = this->canvas.getHeight();
|
||||
this->relativeY = this->canvas->getHeight();
|
||||
} else {
|
||||
this->relativeY = this->parent->getHeight();
|
||||
}
|
||||
@ -117,7 +116,7 @@ void UIComponent::setTransform(
|
||||
this->updatePositions();
|
||||
}
|
||||
|
||||
void UIComponent::draw(UIShader &uiShader, glm::mat4 parentTransform) {
|
||||
void UIComponent::draw(UIShader *uiShader, glm::mat4 parentTransform) {
|
||||
// Calculate self transform matrix
|
||||
glm::mat4 selfTransform = parentTransform * glm::translate(
|
||||
glm::mat4(1.0f), glm::vec3(this->relativeX, this->relativeY, this->z)
|
||||
|
@ -56,12 +56,12 @@ namespace Dawn {
|
||||
* @param uiShader UI Shader for the child to use.
|
||||
* @param selfTransform Self alignment transform.
|
||||
*/
|
||||
virtual void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) = 0;
|
||||
virtual void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) = 0;
|
||||
|
||||
public:
|
||||
UICanvas &canvas;
|
||||
UICanvas *canvas;
|
||||
|
||||
UIComponent(UICanvas &canvas);
|
||||
UIComponent(UICanvas *canvas);
|
||||
|
||||
/**
|
||||
* Returns the calculated width, based on the internal alignment values.
|
||||
@ -106,7 +106,7 @@ namespace Dawn {
|
||||
float_t z
|
||||
);
|
||||
|
||||
void draw(UIShader &uiShader, glm::mat4 parentTransform);
|
||||
void draw(UIShader *uiShader, glm::mat4 parentTransform);
|
||||
|
||||
/**
|
||||
* Adds a child to this UI Component.
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
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->text.size() == 0) return;
|
||||
|
||||
float_t width = this->getWidth();
|
||||
if(width == 0) width = -1;
|
||||
|
||||
this->font->buffer(
|
||||
this->text,
|
||||
this->fontSize,
|
||||
this->getWidth(),
|
||||
this->mesh,
|
||||
width,
|
||||
&this->mesh,
|
||||
&this->measure
|
||||
);
|
||||
|
||||
@ -51,15 +54,15 @@ void UILabel::setFontSize(float_t fontSize) {
|
||||
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;
|
||||
|
||||
this->updateMesh();
|
||||
shader.setUIColor(this->textColor);
|
||||
shader.setUIModel(selfTransform);
|
||||
shader.setUITexture(&this->font->getTexture());
|
||||
shader->setUIColor(this->textColor);
|
||||
shader->setUIModel(selfTransform);
|
||||
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(
|
||||
|
@ -27,8 +27,8 @@ namespace Dawn {
|
||||
/** The colour of this label */
|
||||
struct Color textColor = COLOR_MAGENTA;
|
||||
|
||||
UILabel(UICanvas &canvas);
|
||||
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
|
||||
UILabel(UICanvas *canvas);
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
void setTransform(
|
||||
UIComponentAlign xAlign,
|
||||
UIComponentAlign yAlign,
|
||||
|
@ -1,33 +1,33 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UISprite.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UISprite::UISprite(UICanvas &canvas) : UIComponent(canvas) {
|
||||
this->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
|
||||
}
|
||||
|
||||
void UISprite::updatePositions() {
|
||||
UIComponent::updatePositions();
|
||||
|
||||
QuadMesh::bufferQuadMesh(
|
||||
&this->mesh,
|
||||
glm::vec2(0, 0), glm::vec2(0, 0),
|
||||
glm::vec2(this->width, this->height), glm::vec2(1, 1),
|
||||
0, 0
|
||||
);
|
||||
}
|
||||
|
||||
void UISprite::drawSelf(UIShader &uiShader, glm::mat4 selfTransform) {
|
||||
uiShader.setUITexture(nullptr);
|
||||
uiShader.setUIModel(selfTransform);
|
||||
uiShader.setUIModel(glm::mat4(1.0f));
|
||||
uiShader.setUIColor(COLOR_WHITE);
|
||||
uiShader.setUITexture(this->texture);
|
||||
|
||||
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "UISprite.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
UISprite::UISprite(UICanvas *canvas) : UIComponent(canvas) {
|
||||
this->mesh.createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT);
|
||||
}
|
||||
|
||||
void UISprite::updatePositions() {
|
||||
UIComponent::updatePositions();
|
||||
|
||||
QuadMesh::bufferQuadMesh(
|
||||
&this->mesh,
|
||||
glm::vec2(0, 0), glm::vec2(0, 0),
|
||||
glm::vec2(this->width, this->height), glm::vec2(1, 1),
|
||||
0, 0
|
||||
);
|
||||
}
|
||||
|
||||
void UISprite::drawSelf(UIShader *uiShader, glm::mat4 selfTransform) {
|
||||
uiShader->setUITexture(nullptr);
|
||||
uiShader->setUIModel(selfTransform);
|
||||
uiShader->setUIModel(glm::mat4(1.0f));
|
||||
uiShader->setUIColor(COLOR_WHITE);
|
||||
uiShader->setUITexture(this->texture);
|
||||
|
||||
this->mesh.draw(MESH_DRAW_MODE_TRIANGLES, 0, -1);
|
||||
}
|
@ -12,7 +12,7 @@ namespace Dawn {
|
||||
class UISprite : public UIComponent {
|
||||
protected:
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader &uiShader, glm::mat4 selfTransform) override;
|
||||
void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) override;
|
||||
|
||||
public:
|
||||
Mesh mesh;
|
||||
@ -23,6 +23,6 @@ namespace Dawn {
|
||||
*
|
||||
* @param canvas Canvas that this sprite belongs to.
|
||||
*/
|
||||
UISprite(UICanvas &canvas);
|
||||
UISprite(UICanvas *canvas);
|
||||
};
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
VisualNovelTextbox::VisualNovelTextbox(UICanvas &canvas) :
|
||||
VisualNovelTextbox::VisualNovelTextbox(UICanvas *canvas) :
|
||||
UIComponent(canvas),
|
||||
border(canvas),
|
||||
label(canvas)
|
||||
@ -21,7 +21,7 @@ VisualNovelTextbox::VisualNovelTextbox(UICanvas &canvas) :
|
||||
this->label.startQuad = 0;
|
||||
this->label.quadCount = 0;
|
||||
|
||||
this->canvas.getScene().eventSceneUnpausedUpdate.addListener(
|
||||
this->canvas->getScene()->eventSceneUnpausedUpdate.addListener(
|
||||
this, &VisualNovelTextbox::textboxOnSceneUpdate
|
||||
);
|
||||
}
|
||||
@ -53,15 +53,15 @@ void VisualNovelTextbox::updatePositions() {
|
||||
}
|
||||
|
||||
void VisualNovelTextbox::textboxOnSceneUpdate() {
|
||||
DawnGame &game = this->canvas.getGame();
|
||||
DawnGame *game = this->canvas->getGame();
|
||||
|
||||
if(this->hasRevealedAllCurrentCharacters()) {
|
||||
if(this->hasRevealedAllCharacters()) {
|
||||
if(game.inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
this->eventClose.invoke();
|
||||
}
|
||||
} else {
|
||||
if(game.inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) {
|
||||
this->lineCurrent += this->getCountOfVisibleLines();
|
||||
this->label.startQuad = 0;
|
||||
for(int32_t i = 0; i < this->lineCurrent; i++) {
|
||||
@ -90,10 +90,10 @@ void VisualNovelTextbox::textboxOnSceneUpdate() {
|
||||
}
|
||||
|
||||
auto lastTimeCharacter = (int32_t)mathFloorFloat(this->timeCharacter);
|
||||
if(game.inputManager.isDown(INPUT_BIND_ACCEPT)) {
|
||||
this->timeCharacter += game.timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED_FASTER;
|
||||
if(game->inputManager.isDown(INPUT_BIND_ACCEPT)) {
|
||||
this->timeCharacter += game->timeManager.delta * VISUAL_NOVEL_TEXTBOX_SPEED_FASTER;
|
||||
} 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);
|
||||
if(newTimeCharacter == lastTimeCharacter) return;
|
||||
@ -114,7 +114,7 @@ int32_t VisualNovelTextbox::getCountOfVisibleLines() {
|
||||
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) {
|
||||
this->border.texture = texture;
|
||||
@ -156,7 +156,7 @@ bool_t VisualNovelTextbox::hasRevealedAllCharacters() {
|
||||
}
|
||||
|
||||
VisualNovelTextbox::~VisualNovelTextbox() {
|
||||
this->canvas.getScene().eventSceneUnpausedUpdate.removeListener(
|
||||
this->canvas->getScene()->eventSceneUnpausedUpdate.removeListener(
|
||||
this, &VisualNovelTextbox::textboxOnSceneUpdate
|
||||
);
|
||||
}
|
@ -22,7 +22,7 @@ namespace Dawn {
|
||||
float_t timeCharacter = 0.0f;
|
||||
|
||||
void updatePositions() override;
|
||||
void drawSelf(UIShader &shader, glm::mat4 selfTransform) override;
|
||||
void drawSelf(UIShader *shader, glm::mat4 selfTransform) override;
|
||||
|
||||
/**
|
||||
* Listens for scene updates.
|
||||
@ -44,17 +44,12 @@ namespace Dawn {
|
||||
Event<> eventAllCharactersRevealed;
|
||||
Event<> eventClose;
|
||||
|
||||
VisualNovelTextbox(UICanvas &canvas);
|
||||
|
||||
|
||||
|
||||
VisualNovelTextbox(UICanvas *canvas);
|
||||
void setFont(Font *font);
|
||||
void setBorder(Texture *texture, glm::vec2 dimensions);
|
||||
void setText(std::string text, float_t fontSize);
|
||||
|
||||
bool_t hasRevealedAllCurrentCharacters();
|
||||
bool_t hasRevealedAllCharacters();
|
||||
|
||||
~VisualNovelTextbox();
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user