ADD: Upload Intermediate Assets to GPU, closes #18
All checks were successful
Tests / test (push) Successful in 3m2s
All checks were successful
Tests / test (push) Successful in 3m2s
This commit is contained in:
parent
b71aa63b71
commit
89e98d0f88
@ -29,7 +29,7 @@ FetchContent_Declare(
|
|||||||
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
GIT_REPOSITORY https://github.com/catchorg/Catch2.git
|
||||||
GIT_TAG v3.7.1
|
GIT_TAG v3.7.1
|
||||||
)
|
)
|
||||||
FetchContent_MakeAvailable(Catch2)
|
|
||||||
|
|
||||||
add_executable(LayoutEngineTests
|
add_executable(LayoutEngineTests
|
||||||
tests/layout/LayoutEngineTest.cpp
|
tests/layout/LayoutEngineTest.cpp
|
||||||
@ -38,7 +38,18 @@ target_include_directories(LayoutEngineTests PRIVATE
|
|||||||
src
|
src
|
||||||
lib/glm
|
lib/glm
|
||||||
)
|
)
|
||||||
target_link_libraries(LayoutEngineTests PRIVATE Catch2::Catch2WithMain)
|
|
||||||
|
include(FetchContent)
|
||||||
|
|
||||||
|
FetchContent_Declare(
|
||||||
|
spdlog
|
||||||
|
GIT_REPOSITORY https://github.com/gabime/spdlog.git
|
||||||
|
GIT_TAG v1.17.0
|
||||||
|
)
|
||||||
|
|
||||||
|
FetchContent_MakeAvailable(Catch2 spdlog)
|
||||||
|
|
||||||
|
target_link_libraries(LayoutEngineTests PRIVATE Catch2::Catch2WithMain spdlog::spdlog)
|
||||||
|
|
||||||
include(CTest)
|
include(CTest)
|
||||||
include(Catch)
|
include(Catch)
|
||||||
@ -322,6 +333,7 @@ if(BUILD_GAME)
|
|||||||
glad
|
glad
|
||||||
OpenGL::GL
|
OpenGL::GL
|
||||||
${FREETYPE_LIBRARIES}
|
${FREETYPE_LIBRARIES}
|
||||||
|
spdlog::spdlog
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "OBJLoader.h"
|
#include "OBJLoader.h"
|
||||||
|
#include "spdlog/spdlog.h"
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
using namespace nlohmann;
|
using namespace nlohmann;
|
||||||
@ -122,6 +123,34 @@ std::shared_ptr<UiTheme> AssetManager::loadUiTheme(const std::string &themeName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetManager::insertLoadedTexture(const std::string &name, const Texture2D &texture) {
|
||||||
|
if (textures.contains(name)) {
|
||||||
|
spdlog::warn("Texture '{}' already exists, skipping insert", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
textures[name] = std::make_shared<ModelTexture>(texture.id);
|
||||||
|
spdlog::debug("Texture '{}' inserted successfully", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::insertTexturedModel(const std::string &name, const TexturedModel &textured_model) {
|
||||||
|
if (models.contains(name)) {
|
||||||
|
spdlog::warn("Model '{}' already exists, skipping insert", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
models[name] = std::make_shared<TexturedModel>(textured_model);
|
||||||
|
spdlog::debug("Model '{}' inserted successfully", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetManager::insertModelStages(const std::string &name, ModelStages modelStages) {
|
||||||
|
if (modelsWithStages.contains(name)) {
|
||||||
|
spdlog::warn("Asset '{}' already has stages, skipping insert", name);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
modelsWithStages[name] = std::make_shared<ModelStages>(modelStages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
json AssetManager::readJsonFile(const std::string &path) {
|
json AssetManager::readJsonFile(const std::string &path) {
|
||||||
|
|||||||
@ -10,6 +10,7 @@
|
|||||||
#include "json.hpp"
|
#include "json.hpp"
|
||||||
#include "../model/TexturedModel.h"
|
#include "../model/TexturedModel.h"
|
||||||
#include "Loader.h"
|
#include "Loader.h"
|
||||||
|
#include "Texture2D.h"
|
||||||
#include "../../core/gui/text/UiTheme.h"
|
#include "../../core/gui/text/UiTheme.h"
|
||||||
#include "../model/ModelStages.h"
|
#include "../model/ModelStages.h"
|
||||||
|
|
||||||
@ -28,6 +29,11 @@ public:
|
|||||||
static std::shared_ptr<ModelTexture> getTexture(const std::string& texturePath);
|
static std::shared_ptr<ModelTexture> getTexture(const std::string& texturePath);
|
||||||
static std::shared_ptr<UiTheme> getUiTheme(const std::string& themeName);
|
static std::shared_ptr<UiTheme> getUiTheme(const std::string& themeName);
|
||||||
static std::shared_ptr<UiTheme> loadUiTheme(const std::string& themeName, const std::string& themePath);
|
static std::shared_ptr<UiTheme> loadUiTheme(const std::string& themeName, const std::string& themePath);
|
||||||
|
|
||||||
|
static void insertLoadedTexture(const std::string& name, const Texture2D& texture);
|
||||||
|
static void insertTexturedModel(const std::string & name, const TexturedModel & textured_model);
|
||||||
|
static void insertModelStages(const std::string &name, ModelStages modelStages);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline std::unordered_map<std::string, std::shared_ptr<TexturedModel>> models;
|
static inline std::unordered_map<std::string, std::shared_ptr<TexturedModel>> models;
|
||||||
static inline std::unordered_map<std::string, std::shared_ptr<ModelStages>> modelsWithStages;
|
static inline std::unordered_map<std::string, std::shared_ptr<ModelStages>> modelsWithStages;
|
||||||
|
|||||||
@ -158,3 +158,21 @@ RawModelData OBJLoader::loadModel(const std::string &modelPath) {
|
|||||||
}
|
}
|
||||||
return {"", subModels};
|
return {"", subModels};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TexturedModel OBJLoader::uploadToGPU(RawModelData &rawModelData) {
|
||||||
|
Loader loader = Loader::instance();
|
||||||
|
|
||||||
|
std::vector<SubModel> subModels;
|
||||||
|
for (const auto&[vertices, normals, textureCoords, indices, textures] : rawModelData.subModels) {
|
||||||
|
RawModel rawModel = loader.loadToVAO(vertices, normals, textureCoords, indices);
|
||||||
|
|
||||||
|
RawTextureData textureData = textures[0].textureData;
|
||||||
|
const Texture2D texture = TextureLoader::uploadToGPU(textureData);
|
||||||
|
|
||||||
|
auto modelTexture = ModelTexture(texture.id);
|
||||||
|
auto subModel = SubModel(std::make_shared<RawModel>(rawModel), std::make_shared<ModelTexture>(modelTexture));
|
||||||
|
subModels.push_back(subModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TexturedModel(subModels);
|
||||||
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ class OBJLoader {
|
|||||||
public:
|
public:
|
||||||
static std::shared_ptr<TexturedModel> loadModel(const std::string &modelPath, const std::string &texturePath, Loader &loader);
|
static std::shared_ptr<TexturedModel> loadModel(const std::string &modelPath, const std::string &texturePath, Loader &loader);
|
||||||
static RawModelData loadModel(const std::string &modelPath);
|
static RawModelData loadModel(const std::string &modelPath);
|
||||||
|
static TexturedModel uploadToGPU(RawModelData &rawModelData);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -53,15 +53,7 @@ void AssetLoader::stop() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<IntermediateAsset> AssetLoader::processUploadQueue(int maxPerFrame) {
|
|
||||||
std::vector<IntermediateAsset> results;
|
|
||||||
std::lock_guard lock(readyMutex);
|
|
||||||
for (int i = 0; i < maxPerFrame && !readyQueue.empty(); ++i) {
|
|
||||||
results.push_back(std::move(readyQueue.front()));
|
|
||||||
readyQueue.pop();
|
|
||||||
}
|
|
||||||
return results;
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadingProgress AssetLoader::getProgress() const {
|
LoadingProgress AssetLoader::getProgress() const {
|
||||||
return {total.load(), loaded.load()};
|
return {total.load(), loaded.load()};
|
||||||
@ -84,8 +76,8 @@ void AssetLoader::loadingThreadFunc() {
|
|||||||
pendingQueue.pop();
|
pendingQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
IntermediateAsset result = std::visit([](auto& req) -> IntermediateAsset {
|
IntermediateAsset result = std::visit([]<typename T0>(T0& req) -> IntermediateAsset {
|
||||||
using T = std::decay_t<decltype(req)>;
|
using T = std::decay_t<T0>;
|
||||||
if constexpr (std::is_same_v<T, TextureRequest>) {
|
if constexpr (std::is_same_v<T, TextureRequest>) {
|
||||||
return processTextureRequest(req);
|
return processTextureRequest(req);
|
||||||
} else if constexpr (std::is_same_v<T, ModelRequest>) {
|
} else if constexpr (std::is_same_v<T, ModelRequest>) {
|
||||||
@ -98,7 +90,6 @@ void AssetLoader::loadingThreadFunc() {
|
|||||||
{
|
{
|
||||||
std::lock_guard lock(readyMutex);
|
std::lock_guard lock(readyMutex);
|
||||||
readyQueue.push(std::move(result));
|
readyQueue.push(std::move(result));
|
||||||
++loaded;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -151,6 +142,61 @@ nlohmann::json AssetLoader::loadJson(const std::string &path) {
|
|||||||
return nlohmann::json::object();
|
return nlohmann::json::object();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetLoader::processUploadQueue(int maxPerFrame) {
|
||||||
|
auto uploadQueue = determineUploadQueue(maxPerFrame);
|
||||||
|
for (const auto& intermediateAsset : uploadQueue) {
|
||||||
|
std::visit([]<typename T0>(T0& rawData) -> IntermediateAsset {
|
||||||
|
using T = std::decay_t<T0>;
|
||||||
|
if constexpr (std::is_same_v<T, RawTextureData>) {
|
||||||
|
return processIntermediateTextureAsset(rawData);
|
||||||
|
} else if constexpr (std::is_same_v<T, RawModelData>) {
|
||||||
|
return processIntermediateModelAsset(rawData);
|
||||||
|
} else {
|
||||||
|
return processIntermediateStagedModelAsset(rawData);
|
||||||
|
}
|
||||||
|
}, intermediateAsset);
|
||||||
|
++loaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<IntermediateAsset> AssetLoader::determineUploadQueue(const int maxPerFrame) {
|
||||||
|
std::vector<IntermediateAsset> results;
|
||||||
|
std::lock_guard lock(readyMutex);
|
||||||
|
for (int i = 0; i < maxPerFrame && !readyQueue.empty(); ++i) {
|
||||||
|
results.push_back(std::move(readyQueue.front()));
|
||||||
|
readyQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetLoader::processIntermediateTextureAsset(RawTextureData &textureData) {
|
||||||
|
const Texture2D texture = TextureLoader::uploadToGPU(textureData);
|
||||||
|
AssetManager::insertLoadedTexture(textureData.name, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetLoader::processIntermediateModelAsset(RawModelData &modelData) {
|
||||||
|
const TexturedModel texturedModel = OBJLoader::uploadToGPU(modelData);
|
||||||
|
AssetManager::insertTexturedModel(modelData.name, texturedModel);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AssetLoader::processIntermediateStagedModelAsset(const RawStagedModelData &stagedModelData) {
|
||||||
|
ModelStages modelStages;
|
||||||
|
for (const auto&[stageName, conditionKey, minValue, maxValue, modelData] : stagedModelData.stages) {
|
||||||
|
RawModelData rawModelData = modelData;
|
||||||
|
processIntermediateModelAsset(rawModelData);
|
||||||
|
|
||||||
|
const auto model = AssetManager::getModel(stageName);
|
||||||
|
const auto condition = ModelStageCondition(conditionKey, minValue, maxValue);
|
||||||
|
auto modelStageConfiguration = ModelStageConfiguration(model, stageName, condition);
|
||||||
|
modelStages.addModelStage(modelStageConfiguration);
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetManager::insertModelStages(stagedModelData.name, modelStages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ public:
|
|||||||
void start();
|
void start();
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
std::vector<IntermediateAsset> processUploadQueue(int maxPerFrame);
|
void processUploadQueue(int maxPerFrame);
|
||||||
|
|
||||||
LoadingProgress getProgress() const;
|
LoadingProgress getProgress() const;
|
||||||
|
|
||||||
@ -70,6 +70,11 @@ private:
|
|||||||
static RawModelData processModelRequest(const ModelRequest& request);
|
static RawModelData processModelRequest(const ModelRequest& request);
|
||||||
static RawStagedModelData processStagedModelRequest(const StagedModelRequest& request);
|
static RawStagedModelData processStagedModelRequest(const StagedModelRequest& request);
|
||||||
static nlohmann::json loadJson(const std::string& path);
|
static nlohmann::json loadJson(const std::string& path);
|
||||||
|
std::vector<IntermediateAsset> determineUploadQueue(int maxPerFrame);
|
||||||
|
|
||||||
|
static void processIntermediateTextureAsset(RawTextureData &textureData);
|
||||||
|
static void processIntermediateModelAsset(RawModelData &modelData);
|
||||||
|
static void processIntermediateStagedModelAsset(const RawStagedModelData &stagedModelData);
|
||||||
|
|
||||||
// Render-Thread schreibt, Loading Thread liest
|
// Render-Thread schreibt, Loading Thread liest
|
||||||
std::queue<AssetRequest> pendingQueue;
|
std::queue<AssetRequest> pendingQueue;
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "engine/core/Application.h"
|
#include "engine/core/Application.h"
|
||||||
#include "game/DicewarsApp.h"
|
#include "game/DicewarsApp.h"
|
||||||
|
#include "spdlog/spdlog-inl.h"
|
||||||
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||||
|
|
||||||
Application* CreateApplication()
|
Application* CreateApplication()
|
||||||
@ -9,6 +10,9 @@ Application* CreateApplication()
|
|||||||
return new DicewarsApp();
|
return new DicewarsApp();
|
||||||
}
|
}
|
||||||
int main() {
|
int main() {
|
||||||
|
spdlog::set_level(spdlog::level::debug); // oder info für Release
|
||||||
|
spdlog::set_pattern("[%H:%M:%S] [%^%l%$] %v");
|
||||||
|
|
||||||
auto app = CreateApplication();
|
auto app = CreateApplication();
|
||||||
app->run();
|
app->run();
|
||||||
delete app;
|
delete app;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user