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_TAG v3.7.1
|
||||
)
|
||||
FetchContent_MakeAvailable(Catch2)
|
||||
|
||||
|
||||
add_executable(LayoutEngineTests
|
||||
tests/layout/LayoutEngineTest.cpp
|
||||
@ -38,7 +38,18 @@ target_include_directories(LayoutEngineTests PRIVATE
|
||||
src
|
||||
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(Catch)
|
||||
@ -322,6 +333,7 @@ if(BUILD_GAME)
|
||||
glad
|
||||
OpenGL::GL
|
||||
${FREETYPE_LIBRARIES}
|
||||
spdlog::spdlog
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
|
||||
#include "json.hpp"
|
||||
#include "OBJLoader.h"
|
||||
#include "spdlog/spdlog.h"
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
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) {
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
#include "json.hpp"
|
||||
#include "../model/TexturedModel.h"
|
||||
#include "Loader.h"
|
||||
#include "Texture2D.h"
|
||||
#include "../../core/gui/text/UiTheme.h"
|
||||
#include "../model/ModelStages.h"
|
||||
|
||||
@ -28,6 +29,11 @@ public:
|
||||
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> 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:
|
||||
static inline std::unordered_map<std::string, std::shared_ptr<TexturedModel>> models;
|
||||
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};
|
||||
}
|
||||
|
||||
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:
|
||||
static std::shared_ptr<TexturedModel> loadModel(const std::string &modelPath, const std::string &texturePath, Loader &loader);
|
||||
static RawModelData loadModel(const std::string &modelPath);
|
||||
static TexturedModel uploadToGPU(RawModelData &rawModelData);
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -18,7 +18,7 @@ public:
|
||||
static Texture2D loadTexture(const std::string& path, bool flipVertically= true);
|
||||
static RawTextureData loadRawTextureData(const std::string &path, bool flipVertically = true);
|
||||
static TextureData loadTextureData(const std::string &path, bool flipVertically = true, TextureType textureType);
|
||||
static Texture2D uploadToGPU(RawTextureData& rawTextureData);
|
||||
static Texture2D uploadToGPU(RawTextureData &rawTextureData);
|
||||
static Texture2D uploadToGPU(TextureData& textureData);
|
||||
static void free(Texture2D& texture);
|
||||
};
|
||||
|
||||
@ -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 {
|
||||
return {total.load(), loaded.load()};
|
||||
@ -84,8 +76,8 @@ void AssetLoader::loadingThreadFunc() {
|
||||
pendingQueue.pop();
|
||||
}
|
||||
|
||||
IntermediateAsset result = std::visit([](auto& req) -> IntermediateAsset {
|
||||
using T = std::decay_t<decltype(req)>;
|
||||
IntermediateAsset result = std::visit([]<typename T0>(T0& req) -> IntermediateAsset {
|
||||
using T = std::decay_t<T0>;
|
||||
if constexpr (std::is_same_v<T, TextureRequest>) {
|
||||
return processTextureRequest(req);
|
||||
} else if constexpr (std::is_same_v<T, ModelRequest>) {
|
||||
@ -98,7 +90,6 @@ void AssetLoader::loadingThreadFunc() {
|
||||
{
|
||||
std::lock_guard lock(readyMutex);
|
||||
readyQueue.push(std::move(result));
|
||||
++loaded;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,6 +142,61 @@ nlohmann::json AssetLoader::loadJson(const std::string &path) {
|
||||
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 stop();
|
||||
|
||||
std::vector<IntermediateAsset> processUploadQueue(int maxPerFrame);
|
||||
void processUploadQueue(int maxPerFrame);
|
||||
|
||||
LoadingProgress getProgress() const;
|
||||
|
||||
@ -70,6 +70,11 @@ private:
|
||||
static RawModelData processModelRequest(const ModelRequest& request);
|
||||
static RawStagedModelData processStagedModelRequest(const StagedModelRequest& request);
|
||||
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
|
||||
std::queue<AssetRequest> pendingQueue;
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
#include "engine/core/Application.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.
|
||||
|
||||
Application* CreateApplication()
|
||||
@ -9,6 +10,9 @@ Application* CreateApplication()
|
||||
return new DicewarsApp();
|
||||
}
|
||||
int main() {
|
||||
spdlog::set_level(spdlog::level::debug); // oder info für Release
|
||||
spdlog::set_pattern("[%H:%M:%S] [%^%l%$] %v");
|
||||
|
||||
auto app = CreateApplication();
|
||||
app->run();
|
||||
delete app;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user