Implementing basic asset serialization

This commit is contained in:
Dynamitos
2023-02-13 14:56:13 +01:00
parent 9e1e4076f0
commit 48fa098546
82 changed files with 1834 additions and 423 deletions
+7 -6
View File
@@ -80,6 +80,7 @@ target_link_libraries(Engine PUBLIC dp::thread-pool)
target_link_libraries(Engine PUBLIC crcpp)
target_link_libraries(Engine PUBLIC odeint)
target_link_libraries(Engine PUBLIC zlib)
target_link_libraries(Engine PUBLIC zlibstatic)
if(UNIX)
target_link_libraries(Engine PUBLIC Threads::Threads)
target_link_libraries(Engine PUBLIC dl)
@@ -90,6 +91,10 @@ target_link_libraries(Editor PRIVATE Engine)
target_include_directories(Editor PRIVATE src/Editor)
#target_compile_definitions(Editor PRIVATE EDITOR)
add_executable(AssetViewer "")
target_link_libraries(AssetViewer PRIVATE Engine)
target_include_directories(AssetViewer PRIVATE src/AssetViewer)
target_precompile_headers(Engine
PUBLIC
<assert.h>
@@ -122,16 +127,15 @@ endif()
add_subdirectory(src/)
#add_executable(Seele_unit_tests "")
#add_subdirectory(test/)
add_custom_target(SeeleEngine ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:Engine>
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_RUNTIME_DLLS:Editor> $<TARGET_FILE_DIR:Engine>
COMMAND_EXPAND_LISTS
DEPENDS Editor slang-build)
install(
TARGETS
AssetViewer
Editor
Engine
EnTT
@@ -145,9 +149,6 @@ install(
nlohmann_json
ThreadPool
zlib
slang
slang-glslang
slang-llvm
zlibstatic
IrrXML
odeint
+2 -2
View File
@@ -8,9 +8,9 @@
"generator": "Visual Studio 17 2022 Win64",
"intelliSenseMode": "windows-msvc-x64",
"cmakeExecutable": "D:/Programms/CMake/bin/cmake.exe",
"inheritEnvironments": [],
"inheritEnvironments": [ "msvc_x64" ],
"cmakeCommandArgs": "-DCMAKE_DEBUG_POSTFIX=d -DCMAKE_PLATFORM=x64 -DCMAKE_BUILD_TYPE=Debug",
"buildRoot": "bin/Debug"
"buildRoot": "C:/Users/Dynamitos/Seele/bin/Debug"
},
{
"name": "Release",
+5 -5
View File
@@ -1,7 +1,7 @@
include (ExternalProject)
#--------------ZLIB------------------------------
add_subdirectory(${ZLIB_ROOT})
add_subdirectory(${ZLIB_ROOT} ${ZLIB_ROOT})
#--------------FreeType------------------------------
add_subdirectory(${FREETYPE_ROOT})
@@ -60,7 +60,7 @@ ExternalProject_Add(slang-build
SOURCE_DIR ${SLANG_ROOT}
BINARY_DIR ${SLANG_ROOT}
CONFIGURE_COMMAND ${SLANG_ROOT}/premake.bat vs2019 --file=${SLANG_ROOT}/premake5.lua gmake --arch=${CMAKE_PLATFORM} --deps=true
BUILD_COMMAND msbuild slang.sln -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM}
BUILD_COMMAND msbuild slang.sln -p:PlatformToolset=v143 -p:Configuration=Release -p:Platform=${CMAKE_PLATFORM}
INSTALL_COMMAND ""
)
elseif(UNIX)
@@ -73,7 +73,7 @@ ExternalProject_Add(slang-build
)
endif()
add_library(slang-llvm INTERFACE)
add_library(slang-llvm SHARED IMPORTED)
target_link_libraries(slang-llvm INTERFACE
$<BUILD_INTERFACE:${SLANG_BINARY_DIR}/slang.lib>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/slang.lib>
@@ -81,7 +81,7 @@ target_link_libraries(slang-llvm INTERFACE
set_target_properties(slang-llvm PROPERTIES IMPORTED_IMPLIB ${SLANG_BINARY_DIR}/slang.lib)
set_target_properties(slang-llvm PROPERTIES IMPORTED_LOCATION ${SLANG_BINARY_DIR}/slang-llvm.dll)
add_library(slang-glslang INTERFACE)
add_library(slang-glslang SHARED IMPORTED)
target_link_libraries(slang-glslang INTERFACE
$<BUILD_INTERFACE:${SLANG_BINARY_DIR}/slang.lib>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/lib/slang.lib>
@@ -89,7 +89,7 @@ target_link_libraries(slang-glslang INTERFACE
set_target_properties(slang-glslang PROPERTIES IMPORTED_IMPLIB ${SLANG_BINARY_DIR}/slang.lib)
set_target_properties(slang-glslang PROPERTIES IMPORTED_LOCATION ${SLANG_BINARY_DIR}/slang-glslang.dll)
add_library(slang INTERFACE)
add_library(slang SHARED IMPORTED)
target_include_directories(slang INTERFACE
$<BUILD_INTERFACE:${SLANG_ROOT}/>
+1 -1
+3
View File
@@ -0,0 +1,3 @@
target_sources(AssetViewer
PRIVATE
main.cpp)
+62
View File
@@ -0,0 +1,62 @@
#include "Asset/Asset.h"
#include "Asset/MeshAsset.h"
#include "Asset/FontAsset.h"
#include "Asset/TextureAsset.h"
#include "Asset/MaterialAsset.h"
#include "Asset/MaterialInstanceAsset.h"
#include "Graphics/Vulkan/VulkanGraphics.h"
#include "Asset/AssetRegistry.h"
using namespace Seele;
AssetRegistry * instance = new AssetRegistry();
int main(int argc, char** argv)
{
//if(argc < 2)
//{
// return -1;
//}
std::filesystem::path path = "C:\\Users\\Dynamitos\\TrackClear\\Assets\\Dirt.asset";
std::ifstream stream = std::ifstream(path, std::ios::binary);
ArchiveBuffer buffer;
buffer.readFromStream(stream);
// Read asset type
uint64 identifier;
Serialization::load(buffer, identifier);
// Read name
std::string name;
Serialization::load(buffer, name);
// Read folder
std::string folderPath;
Serialization::load(buffer, folderPath);
PAsset asset;
switch (identifier)
{
case TextureAsset::IDENTIFIER:
asset = new TextureAsset(folderPath, name);
break;
case MeshAsset::IDENTIFIER:
asset = new MeshAsset(folderPath, name);
break;
case MaterialAsset::IDENTIFIER:
asset = new MaterialAsset(folderPath, name);
break;
case MaterialInstanceAsset::IDENTIFIER:
asset = new MaterialInstanceAsset(folderPath, name);
// TODO
break;
case FontAsset::IDENTIFIER:
asset = new FontAsset(folderPath, name);
break;
default:
throw new std::logic_error("Unknown Identifier");
}
asset->load(buffer);
std::cin.get();
}
+1
View File
@@ -1,2 +1,3 @@
add_subdirectory(AssetViewer/)
add_subdirectory(Editor/)
add_subdirectory(Engine/)
+173 -1
View File
@@ -4,6 +4,9 @@
#include "Component/KeyboardInput.h"
#include "Actor/CameraActor.h"
#include "Asset/AssetRegistry.h"
#include "Asset/MeshLoader.h"
#include "Asset/TextureLoader.h"
#include "Asset/MaterialLoader.h"
using namespace Seele;
@@ -24,7 +27,176 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
{
scene = new Scene(graphics);
gameInterface.reload(instance);
gameInterface.getGame()->importAssets();
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/arena.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/train.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/bird.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/cube.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/flameThrower.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/player.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/shotgun.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/track.fbx",
});
AssetRegistry::importMesh(MeshImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/zombie.fbx",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Dirt.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/DirtGrass.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Grass.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Ice.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Lava.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Obsidian.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Rocks.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Sand.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Water.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Wood.png",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/blendMap.png",
.importPath = "level0",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/heightMap.png",
.importPath = "level0",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/trackMap.png",
.importPath = "level0",
});
AssetRegistry::importMaterial(MaterialImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/TerrainLevel0.asset",
.importPath = "level0",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/blendMap.png",
.importPath = "level1",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/heightMap.png",
.importPath = "level1",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/trackMap.png",
.importPath = "level1",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/blendMap.png",
.importPath = "level2",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/heightMap.png",
.importPath = "level2",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/trackMap.png",
.importPath = "level2",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/blendMap.png",
.importPath = "level3",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/heightMap.png",
.importPath = "level3",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/trackMap.png",
.importPath = "level3",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/blendMap.png",
.importPath = "level4",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/heightMap.png",
.importPath = "level4",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/trackMap.png",
.importPath = "level4",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/blendMap.png",
.importPath = "level5",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/heightMap.png",
.importPath = "level5",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/trackMap.png",
.importPath = "level5",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/blendMap.png",
.importPath = "level6",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/heightMap.png",
.importPath = "level6",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/trackMap.png",
.importPath = "level6",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/blendMap.png",
.importPath = "level7",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/heightMap.png",
.importPath = "level7",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/trackMap.png",
.importPath = "level7",
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/skyboxes/FS000_Day_01.png",
.type = TextureImportType::TEXTURE_CUBEMAP,
});
AssetRegistry::importTexture(TextureImportArgs {
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/skyboxes/FS000_Night_01.png",
.type = TextureImportType::TEXTURE_CUBEMAP,
});
AssetRegistry::saveRegistry();
systemGraph = new SystemGraph();
gameInterface.getGame()->setupScene(scene, systemGraph);
renderGraph.updateViewport(viewport);
+4 -1
View File
@@ -3,6 +3,7 @@
#include "Window/GameView.h"
#include "Window/InspectorView.h"
#include "Asset/AssetRegistry.h"
#include "Asset/TextureLoader.h"
#include "Graphics/Vulkan/VulkanGraphics.h"
using namespace Seele;
@@ -11,10 +12,12 @@ using namespace Seele::Editor;
int main()
{
Gfx::PGraphics graphics = new Vulkan::Graphics();
GraphicsInitializer initializer;
graphics->init(initializer);
PWindowManager windowManager = new WindowManager();
AssetRegistry::init(std::string("C:\\Users\\Dynamitos\\TrackClear"), graphics);
AssetRegistry::init(std::string("C:\\Users\\Dynamitos\\TrackClear\\Assets"), graphics);
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280;
+14 -31
View File
@@ -1,64 +1,47 @@
#include "Asset.h"
#include "AssetRegistry.h"
#include "Graphics/Graphics.h"
using namespace Seele;
Asset::Asset()
: fullPath("")
: folderPath("")
, name("")
, parentDir("")
, extension("")
, status(Status::Uninitialized)
, byteSize(0)
{
}
Asset::Asset(const std::filesystem::path& path)
Asset::Asset(std::string_view _folderPath, std::string_view _name)
: status(Status::Uninitialized)
, folderPath(_folderPath)
, name(_name)
{
if(path.is_absolute())
if (folderPath.empty())
{
fullPath = path;
assetId = name;
}
else
{
fullPath = AssetRegistry::getRootFolder();
fullPath.append(path.generic_string());
assetId = folderPath + "/" + name;
}
fullPath.make_preferred();
parentDir = fullPath.parent_path();
name = fullPath.stem();
extension = fullPath.extension();
}
Asset::Asset(const std::string &directory, const std::string &fileName)
: Asset(std::filesystem::path(directory + fileName))
{
}
Asset::~Asset()
{
}
std::ifstream Asset::getReadStream() const
std::string Asset::getFolderPath() const
{
return std::ifstream(fullPath, std::ios::binary);
return folderPath;
}
std::ofstream Asset::getWriteStream() const
std::string Asset::getName() const
{
return std::ofstream(fullPath, std::ios::binary);
return name;
}
std::string Asset::getFileName() const
std::string Asset::getAssetIdentifier() const
{
return name.generic_string();
}
std::string Asset::getFullPath() const
{
return fullPath.generic_string();
}
std::string Asset::getExtension() const
{
return extension.generic_string();
return assetId;
}
+16 -23
View File
@@ -1,5 +1,6 @@
#pragma once
#include "MinimalEngine.h"
#include "Serialization/ArchiveBuffer.h"
namespace Seele
{
@@ -14,39 +15,31 @@ public:
Ready
};
Asset();
Asset(const std::string& directory, const std::string& name);
Asset(const std::filesystem::path& path);
Asset(std::string_view folderPath, std::string_view name);
virtual ~Asset();
virtual void save(Gfx::PGraphics graphics) = 0;
virtual void load(Gfx::PGraphics graphics) = 0;
virtual void save(ArchiveBuffer& buffer) const = 0;
virtual void load(ArchiveBuffer& buffer) = 0;
// returns the name of the file, without extension
std::string getFileName() const;
// returns the full absolute path, from root to extension
std::string getFullPath() const;
// returns the file extension, without preceding dot
std::string getExtension() const;
inline Status getStatus()
// returns the assets name
std::string getName() const;
// returns the (virtual) folder path
std::string getFolderPath() const;
// returns the identifier with which it can be found from the asset registry
std::string getAssetIdentifier() const;
constexpr Status getStatus()
{
std::scoped_lock lck(lock);
return status;
}
inline void setStatus(Status _status)
constexpr void setStatus(Status _status)
{
std::scoped_lock lck(lock);
status = _status;
}
protected:
std::mutex lock;
std::ifstream getReadStream() const;
std::ofstream getWriteStream() const;
private:
// Path relative to the project root
std::filesystem::path fullPath;
std::filesystem::path name;
std::filesystem::path parentDir;
std::filesystem::path extension;
std::string folderPath;
std::string name;
std::string assetId;
Status status;
uint32 byteSize;
};
+264 -38
View File
@@ -3,6 +3,7 @@
#include "FontAsset.h"
#include "TextureAsset.h"
#include "MaterialAsset.h"
#include "MaterialInstanceAsset.h"
#include "FontLoader.h"
#include "TextureLoader.h"
#include "MaterialLoader.h"
@@ -15,12 +16,12 @@
#include <iostream>
using namespace Seele;
using json = nlohmann::json;
extern AssetRegistry* instance;
AssetRegistry::~AssetRegistry()
{
delete assetRoot;
}
void AssetRegistry::init(const std::string& rootFolder, Gfx::PGraphics graphics)
@@ -30,28 +31,47 @@ void AssetRegistry::init(const std::string& rootFolder, Gfx::PGraphics graphics)
void AssetRegistry::importMesh(MeshImportArgs args)
{
if (get().getOrCreateFolder(args.importPath)->meshes.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().meshLoader->importAsset(args);
}
void AssetRegistry::importTexture(TextureImportArgs args)
{
if (get().getOrCreateFolder(args.importPath)->textures.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().textureLoader->importAsset(args);
}
void AssetRegistry::importFont(FontImportArgs args)
{
if (get().getOrCreateFolder(args.importPath)->fonts.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().fontLoader->importAsset(args);
}
void AssetRegistry::importMaterial(MaterialImportArgs args)
{
if (get().getOrCreateFolder(args.importPath)->materials.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().materialLoader->importAsset(args);
}
PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
{
AssetFolder& folder = get().assetRoot;
AssetFolder* folder = get().assetRoot;
std::string fileName = filePath;
size_t slashLoc = filePath.rfind("/");
if(slashLoc != -1)
@@ -59,30 +79,25 @@ PMeshAsset AssetRegistry::findMesh(const std::string &filePath)
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
fileName = filePath.substr(slashLoc+1, filePath.size());
}
auto it = folder.meshes.find(fileName);
assert(it != folder.meshes.end());
return it->second;
return folder->meshes.at(fileName);
}
PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
{
AssetFolder* folder = get().assetRoot;
std::string fileName = filePath;
size_t slashLoc = filePath.rfind("/");
if(slashLoc != -1)
if (slashLoc != -1)
{
AssetFolder& folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
fileName = filePath.substr(slashLoc+1, filePath.size());
return folder.textures[fileName];
}
else
{
return get().assetRoot.textures[fileName];
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
fileName = filePath.substr(slashLoc + 1, filePath.size());
}
return folder->textures.at(fileName);
}
PFontAsset AssetRegistry::findFont(const std::string& filePath)
{
AssetFolder& folder = get().assetRoot;
AssetFolder* folder = get().assetRoot;
std::string fileName = filePath;
size_t slashLoc = filePath.rfind("/");
if(slashLoc != -1)
@@ -90,20 +105,20 @@ PFontAsset AssetRegistry::findFont(const std::string& filePath)
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
fileName = filePath.substr(slashLoc+1, filePath.size());
}
return folder.fonts[fileName];
return folder->fonts.at(fileName);
}
PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath)
{
AssetFolder& folder = get().assetRoot;
AssetFolder* folder = get().assetRoot;
std::string fileName = filePath;
size_t slashLoc = filePath.rfind("/");
if(slashLoc != -1)
if (slashLoc != -1)
{
folder = get().getOrCreateFolder(filePath.substr(0, slashLoc));
fileName = filePath.substr(slashLoc+1, filePath.size());
fileName = filePath.substr(slashLoc + 1, filePath.size());
}
return folder.materials[fileName];
return folder->materials.at(fileName);
}
std::ofstream AssetRegistry::createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
@@ -125,57 +140,256 @@ AssetRegistry::AssetRegistry()
{
}
void AssetRegistry::loadRegistry()
{
get().loadRegistryInternal();
}
void AssetRegistry::saveRegistry()
{
get().saveRegistryInternal();
}
void AssetRegistry::initialize(const std::filesystem::path &_rootFolder, Gfx::PGraphics _graphics)
{
this->graphics = _graphics;
this->rootFolder = _rootFolder;
this->assetRoot = new AssetFolder("");
this->fontLoader = new FontLoader(graphics);
this->meshLoader = new MeshLoader(graphics);
this->textureLoader = new TextureLoader(graphics);
this->materialLoader = new MaterialLoader(graphics);
loadRegistryInternal();
}
std::string AssetRegistry::getRootFolder()
void AssetRegistry::loadRegistryInternal()
{
return get().rootFolder.generic_string();
peekFolder(assetRoot);
loadFolder(assetRoot);
}
void AssetRegistry::registerMesh(PMeshAsset mesh, const std::string& importPath)
void AssetRegistry::peekFolder(AssetFolder* folder)
{
AssetFolder& folder = getOrCreateFolder(importPath);
folder.meshes[mesh->getFileName()] = mesh;
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath))
{
const auto& stem = entry.path().stem().string();
if (entry.is_directory())
{
if (folder->folderPath.empty())
{
folder->children[stem] = new AssetFolder(stem);
}
else
{
folder->children[stem] = new AssetFolder(folder->folderPath + "/" + stem);
}
peekFolder(folder->children[stem]);
continue;
}
auto stream = std::ifstream(entry.path(), std::ios::binary);
ArchiveBuffer buffer(graphics);
buffer.readFromStream(stream);
// Read asset type
uint64 identifier;
Serialization::load(buffer, identifier);
// Read name
std::string name;
Serialization::load(buffer, name);
// Read folder
std::string folderPath;
Serialization::load(buffer, folderPath);
PAsset asset;
switch (identifier)
{
case TextureAsset::IDENTIFIER:
asset = new TextureAsset(folderPath, name);
folder->textures[asset->getName()] = asset;
break;
case MeshAsset::IDENTIFIER:
asset = new MeshAsset(folderPath, name);
folder->meshes[asset->getName()] = asset;
break;
case MaterialAsset::IDENTIFIER:
asset = new MaterialAsset(folderPath, name);
folder->materials[asset->getName()] = asset;
break;
case MaterialInstanceAsset::IDENTIFIER:
asset = new MaterialInstanceAsset(folderPath, name);
// TODO
break;
case FontAsset::IDENTIFIER:
asset = new FontAsset(folderPath, name);
folder->fonts[asset->getName()] = asset;
break;
default:
throw new std::logic_error("Unknown Identifier");
}
}
}
void AssetRegistry::registerTexture(PTextureAsset texture, const std::string& importPath)
void AssetRegistry::loadFolder(AssetFolder* folder)
{
AssetFolder& folder = getOrCreateFolder(importPath);
folder.textures[texture->getFileName()] = texture;
for (const auto& entry : std::filesystem::directory_iterator(rootFolder / folder->folderPath))
{
const auto& path = entry.path();
if (entry.is_directory())
{
auto relative = path.stem().string();
loadFolder(folder->children[relative]);
continue;
}
auto stream = std::ifstream(path, std::ios::binary);
ArchiveBuffer buffer(graphics);
buffer.readFromStream(stream);
// Read asset type
uint64 identifier;
Serialization::load(buffer, identifier);
// Read name
std::string name;
Serialization::load(buffer, name);
// Read folder
std::string folderPath;
Serialization::load(buffer, folderPath);
PAsset asset;
switch (identifier)
{
case TextureAsset::IDENTIFIER:
asset = folder->textures.at(name);
break;
case MeshAsset::IDENTIFIER:
asset = folder->meshes.at(name);
break;
case MaterialAsset::IDENTIFIER:
asset = folder->materials.at(name);
break;
case MaterialInstanceAsset::IDENTIFIER:
//asset = new MaterialInstanceAsset(path);
// TODO
break;
case FontAsset::IDENTIFIER:
asset = folder->fonts.at(name);
break;
default:
throw new std::logic_error("Unknown Identifier");
}
asset->load(buffer);
}
}
void AssetRegistry::registerFont(PFontAsset font, const std::string& importPath)
void AssetRegistry::saveRegistryInternal()
{
AssetFolder& folder = getOrCreateFolder(importPath);
folder.fonts[font->getFileName()] = font;
saveFolder("", assetRoot);
}
void AssetRegistry::registerMaterial(PMaterialAsset material, const std::string& importPath)
void AssetRegistry::saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder)
{
AssetFolder& folder = getOrCreateFolder(importPath);
folder.materials[material->getFileName()] = material;
std::filesystem::create_directory(rootFolder / folderPath);
for (const auto& [name, texture] : folder->textures)
{
saveAsset(texture, TextureAsset::IDENTIFIER, folderPath, name);
}
for (const auto& [name, mesh] : folder->meshes)
{
saveAsset(mesh, MeshAsset::IDENTIFIER, folderPath, name);
}
for (const auto& [name, material] : folder->materials)
{
saveAsset(material, MaterialAsset::IDENTIFIER, folderPath, name);
}
for (const auto& [name, font] : folder->fonts)
{
saveAsset(font, FontAsset::IDENTIFIER, folderPath, name);
}
for (auto& [name, child] : folder->children)
{
saveFolder(folderPath / name, child);
}
}
AssetRegistry::AssetFolder& AssetRegistry::getOrCreateFolder(std::string fullPath)
void AssetRegistry::saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name)
{
AssetFolder& result = assetRoot;
if (name.empty())
return;
std::string path = (folderPath / name).string().append(".asset");
auto assetStream = createWriteStream(std::move(path), std::ios::binary);
ArchiveBuffer assetBuffer(graphics);
// write identifier
Serialization::save(assetBuffer, identifier);
// write name
Serialization::save(assetBuffer, name);
// write folder
Serialization::save(assetBuffer, folderPath.string());
// write asset data
asset->save(assetBuffer);
assetBuffer.writeToStream(assetStream);
}
std::filesystem::path AssetRegistry::getRootFolder()
{
return get().rootFolder;
}
void AssetRegistry::registerMesh(PMeshAsset mesh)
{
AssetFolder* folder = getOrCreateFolder(mesh->getFolderPath());
folder->meshes[mesh->getName()] = mesh;
}
void AssetRegistry::registerTexture(PTextureAsset texture)
{
AssetFolder* folder = getOrCreateFolder(texture->getFolderPath());
folder->textures[texture->getName()] = texture;
}
void AssetRegistry::registerFont(PFontAsset font)
{
AssetFolder* folder = getOrCreateFolder(font->getFolderPath());
folder->fonts[font->getName()] = font;
}
void AssetRegistry::registerMaterial(PMaterialAsset material)
{
AssetFolder* folder = getOrCreateFolder(material->getFolderPath());
folder->materials[material->getName()] = material;
}
AssetRegistry::AssetFolder* AssetRegistry::getOrCreateFolder(std::string fullPath)
{
AssetFolder* result = assetRoot;
std::string temp = fullPath;
while(!fullPath.empty())
{
size_t slashLoc = fullPath.find("/");
if(slashLoc == -1)
{
return result.children[fullPath];
if (!result->children.contains(fullPath))
{
result->children[fullPath] = new AssetFolder(fullPath);
}
return result->children[fullPath];
}
std::string folderName = fullPath.substr(0, slashLoc);
result = result.children[folderName];
if (!result->children.contains(folderName))
{
result->children[folderName] = new AssetFolder(temp);
}
result = result->children[folderName];
fullPath = fullPath.substr(slashLoc+1, fullPath.size());
}
return result;
@@ -194,3 +408,15 @@ std::ifstream AssetRegistry::internalCreateReadStream(const std::string& relativ
fullPath.append(relativePath);
return std::ifstream(fullPath.string(), openmode);
}
AssetRegistry::AssetFolder::AssetFolder(std::string_view folderPath)
: folderPath(folderPath)
{}
AssetRegistry::AssetFolder::~AssetFolder()
{
for (const auto& [_, child] : children)
{
delete child;
}
}
+26 -14
View File
@@ -1,8 +1,8 @@
#pragma once
#include "MinimalEngine.h"
#include "Asset.h"
#include "Containers/Map.h"
#include <string>
#include <map>
namespace Seele
{
@@ -22,7 +22,7 @@ public:
~AssetRegistry();
static void init(const std::string& rootFolder, Gfx::PGraphics graphics);
static std::string getRootFolder();
static std::filesystem::path getRootFolder();
static PMeshAsset findMesh(const std::string& filePath);
static PTextureAsset findTexture(const std::string& filePath);
@@ -37,35 +37,47 @@ public:
static void importFont(struct FontImportArgs args);
static void importMaterial(struct MaterialImportArgs args);
static void set(AssetRegistry registry);
static void loadRegistry();
static void saveRegistry();
AssetRegistry();
private:
struct AssetFolder
{
std::map<std::string, AssetFolder> children;
std::string folderPath;
Map<std::string, AssetFolder*> children;
//Todo: Seele::Map doesn't really work with strings for some reason, so just use std::map for now
std::map<std::string, PTextureAsset> textures;
std::map<std::string, PFontAsset> fonts;
std::map<std::string, PMeshAsset> meshes;
std::map<std::string, PMaterialAsset> materials;
Map<std::string, PTextureAsset> textures;
Map<std::string, PFontAsset> fonts;
Map<std::string, PMeshAsset> meshes;
Map<std::string, PMaterialAsset> materials;
AssetFolder(std::string_view folderPath);
~AssetFolder();
};
static AssetRegistry& get();
void initialize(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics);
void loadRegistryInternal();
void peekFolder(AssetFolder* folder);
void loadFolder(AssetFolder* folder);
void saveRegistryInternal();
void saveFolder(const std::filesystem::path& folderPath, AssetFolder* folder);
void saveAsset(PAsset asset, uint64 identifier, const std::filesystem::path& folderPath, std::string name);
void registerMesh(PMeshAsset mesh);
void registerTexture(PTextureAsset texture);
void registerFont(PFontAsset font);
void registerMaterial(PMaterialAsset material);
void registerMesh(PMeshAsset mesh, const std::string& importPath);
void registerTexture(PTextureAsset texture, const std::string& importPath);
void registerFont(PFontAsset font, const std::string& importPath);
void registerMaterial(PMaterialAsset material, const std::string& importPath);
AssetFolder& getOrCreateFolder(std::string foldername);
AssetFolder* getOrCreateFolder(std::string foldername);
std::ofstream internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = std::ios::out);
std::ifstream internalCreateReadStream(const std::string& relaitvePath, std::ios_base::openmode openmode = std::ios::in);
std::filesystem::path rootFolder;
AssetFolder assetRoot;
AssetFolder* assetRoot;
Gfx::PGraphics graphics;
UPTextureLoader textureLoader;
UPFontLoader fontLoader;
+103 -9
View File
@@ -1,5 +1,7 @@
#include "FontAsset.h"
#include "Graphics/Graphics.h"
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
#include <ktx.h>
using namespace Seele;
@@ -7,13 +9,8 @@ FontAsset::FontAsset()
{
}
FontAsset::FontAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
FontAsset::FontAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
FontAsset::FontAsset(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
@@ -22,11 +19,108 @@ FontAsset::~FontAsset()
}
void FontAsset::save(Gfx::PGraphics graphics)
void FontAsset::save(ArchiveBuffer& buffer) const
{
uint64 numGlyphs = glyphs.size();
buffer.writeBytes(&numGlyphs, sizeof(uint64));
for (auto& [index, glyph] : glyphs)
{
Serialization::save(buffer, index);
Array<uint8> textureData;
ktxTexture2* kTexture;
ktxTextureCreateInfo createInfo = {
.vkFormat = (uint32_t)glyph.texture->getFormat(),
.baseWidth = glyph.texture->getSizeX(),
.baseHeight = glyph.texture->getSizeY(),
.baseDepth = glyph.texture->getSizeZ(),
.numDimensions = glyph.texture->getSizeZ() > 1 ? 3u : glyph.texture->getSizeY() > 1 ? 2u : 1u,
.numLevels = glyph.texture->getMipLevels(),
.numFaces = glyph.texture->getNumFaces(),
.isArray = false,
.generateMipmaps = false,
};
ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture);
for (uint32 depth = 0; depth < glyph.texture->getSizeZ(); ++depth)
{
for (uint32 face = 0; face < glyph.texture->getNumFaces(); ++face)
{
// technically, downloading cant be const, because we have to allocate temporary buffers and change layouts
// but practically the texture stays the same
glyph.texture->download(0, depth, face, textureData);
ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, depth, face, textureData.data(), textureData.size());
}
}
char writer[100];
snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1");
ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY,
(ktx_uint32_t)strlen(writer) + 1,
writer);
ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_ASTC_4x4_RGBA, 0);
ktx_uint8_t* texData;
ktx_size_t texSize;
ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize);
buffer.writeBytes(texData, texSize);
free(texData);
Serialization::save(buffer, glyph.size);
Serialization::save(buffer, glyph.bearing);
Serialization::save(buffer, glyph.advance);
}
}
void FontAsset::load(Gfx::PGraphics graphics)
void FontAsset::load(ArchiveBuffer& buffer)
{
uint64 numGlyphs = glyphs.size();
buffer.readBytes(&numGlyphs, sizeof(uint64));
for (uint64 x = 0; x < numGlyphs; ++x)
{
uint32 index;
Serialization::load(buffer, index);
Glyph& glyph = glyphs[index];
uint64 texSize;
buffer.readBytes(&texSize, sizeof(uint64));
Array<uint8> rawTex;
rawTex.resize(texSize);
buffer.readBytes(rawTex.data(), rawTex.size());
ktxTexture2* kTexture;
ktxTexture2_CreateFromMemory(rawTex.data(),
rawTex.size(),
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
&kTexture);
ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_BC7_RGBA, 0);
TextureCreateInfo createInfo = {
.resourceData = {
.size = ktxTexture_GetDataSize(ktxTexture(kTexture)),
.data = ktxTexture_GetData(ktxTexture(kTexture)),
.owner = Gfx::QueueType::GRAPHICS,
},
.width = kTexture->baseWidth,
.height = kTexture->baseHeight,
.depth = kTexture->baseDepth,
.bArray = kTexture->isArray,
.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces,
.mipLevels = kTexture->numLevels,
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
};
glyph.texture = buffer.getGraphics()->createTexture2D(createInfo);
ktxTexture_Destroy(ktxTexture(kTexture));
Serialization::load(buffer, glyph.size);
Serialization::load(buffer, glyph.bearing);
Serialization::load(buffer, glyph.advance);
}
}
+6 -4
View File
@@ -1,5 +1,7 @@
#pragma once
#include "Asset.h"
#include "Containers/Map.h"
#include "Math/Math.h"
namespace Seele
{
@@ -7,12 +9,12 @@ DECLARE_NAME_REF(Gfx, Texture2D)
class FontAsset : public Asset
{
public:
static constexpr uint64 IDENTIFIER = 0x10;
FontAsset();
FontAsset(const std::string& directory, const std::string& name);
FontAsset(const std::filesystem::path& fullPath);
FontAsset(std::string_view folderPath, std::string_view name);
virtual ~FontAsset();
virtual void save(Gfx::PGraphics graphics) override;
virtual void load(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
struct Glyph
{
+4 -6
View File
@@ -22,11 +22,9 @@ void FontLoader::importAsset(FontImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PFontAsset asset = new FontAsset(assetPath.generic_string());
std::error_code code;
std::filesystem::copy_file(args.filePath, asset->getFullPath(), code);
PFontAsset asset = new FontAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerFont(asset, args.importPath);
AssetRegistry::get().registerFont(asset);
import(args, asset);
}
@@ -39,7 +37,7 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset)
FT_Error error = FT_Init_FreeType(&ft);
assert(!error);
FT_Face face;
error = FT_New_Face(ft, asset->getFullPath().c_str(), 0, &face);
error = FT_New_Face(ft, args.filePath.string().c_str(), 0, &face);
assert(!error);
FT_Set_Pixel_Sizes(face, 0, 48);
for(uint32 c = 0; c < 256; ++c)
@@ -59,7 +57,7 @@ void FontLoader::import(FontImportArgs args, PFontAsset asset)
imageData.height = face->glyph->bitmap.rows;
imageData.resourceData.data = face->glyph->bitmap.buffer;
imageData.resourceData.size = imageData.width * imageData.height;
if(imageData.width == 0 || imageData.width == 0)
if(imageData.width == 0 || imageData.height == 0)
{
glyph.size.x = 1;
glyph.size.y = 1;
+7 -11
View File
@@ -8,13 +8,8 @@ MaterialAsset::MaterialAsset()
{
}
MaterialAsset::MaterialAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
MaterialAsset::MaterialAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
MaterialAsset::MaterialAsset(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
@@ -22,13 +17,14 @@ MaterialAsset::~MaterialAsset()
{
}
void MaterialAsset::save(Gfx::PGraphics graphics)
void MaterialAsset::save(ArchiveBuffer& buffer) const
{
material->save(buffer);
}
void MaterialAsset::load(Gfx::PGraphics graphics)
void MaterialAsset::load(ArchiveBuffer& buffer)
{
material = new Material();
material->load(buffer);
}
+4 -4
View File
@@ -7,12 +7,12 @@ DECLARE_REF(Material)
class MaterialAsset : public Asset
{
public:
static constexpr uint64 IDENTIFIER = 0x4;
MaterialAsset();
MaterialAsset(const std::string &directory, const std::string &name);
MaterialAsset(const std::filesystem::path &fullPath);
MaterialAsset(std::string_view folderPath, std::string_view name);
virtual ~MaterialAsset();
virtual void save(Gfx::PGraphics graphics) override;
virtual void load(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
PMaterial getMaterial() const { return material; }
private:
PMaterial material;
+4 -9
View File
@@ -9,13 +9,8 @@ MaterialInstanceAsset::MaterialInstanceAsset()
{
}
MaterialInstanceAsset::MaterialInstanceAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
MaterialInstanceAsset::MaterialInstanceAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
MaterialInstanceAsset::MaterialInstanceAsset(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
@@ -24,10 +19,10 @@ MaterialInstanceAsset::~MaterialInstanceAsset()
}
void MaterialInstanceAsset::save(Gfx::PGraphics graphics)
void MaterialInstanceAsset::save(ArchiveBuffer& buffer) const
{
}
void MaterialInstanceAsset::load(Gfx::PGraphics graphics)
void MaterialInstanceAsset::load(ArchiveBuffer& buffer)
{
}
+4 -4
View File
@@ -7,12 +7,12 @@ namespace Seele
class MaterialInstanceAsset : public Asset
{
public:
static constexpr uint64 IDENTIFIER = 0x8;
MaterialInstanceAsset();
MaterialInstanceAsset(const std::string &directory, const std::string &name);
MaterialInstanceAsset(const std::filesystem::path &fullPath);
MaterialInstanceAsset(std::string_view folderPath, std::string_view name);
virtual ~MaterialInstanceAsset();
virtual void save(Gfx::PGraphics graphics) override;
virtual void load(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
private:
PMaterialInstance material;
};
+2 -2
View File
@@ -29,9 +29,9 @@ void MaterialLoader::importAsset(MaterialImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PMaterialAsset asset = new MaterialAsset(assetPath.generic_string());
PMaterialAsset asset = new MaterialAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerMaterial(asset, args.importPath);
AssetRegistry::get().registerMaterial(asset);
import(args, asset);
}
+44 -12
View File
@@ -1,8 +1,10 @@
#include "MeshAsset.h"
#include "Graphics/Graphics.h"
#include "Graphics/Mesh.h"
#include "AssetRegistry.h"
#include "Graphics/VertexShaderInput.h"
#include "Material/MaterialInterface.h"
#include "Graphics/StaticMeshVertexInput.h"
using namespace Seele;
@@ -10,34 +12,64 @@ MeshAsset::MeshAsset()
{
}
MeshAsset::MeshAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
MeshAsset::MeshAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
MeshAsset::MeshAsset(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
MeshAsset::~MeshAsset()
{
}
}
void MeshAsset::save(Gfx::PGraphics graphics)
void MeshAsset::save(ArchiveBuffer& buffer) const
{
uint64 numMeshes = meshes.size();
Serialization::save(buffer, numMeshes);
for (auto mesh : meshes)
{
mesh->vertexInput->save(buffer);
Array<uint8> rawIndices;
mesh->indexBuffer->download(rawIndices);
Serialization::save(buffer, rawIndices);
Serialization::save(buffer, mesh->indexBuffer->getIndexType());
Serialization::save(buffer, mesh->referencedMaterial->getAssetIdentifier());
}
}
void MeshAsset::load(Gfx::PGraphics graphics)
void MeshAsset::load(ArchiveBuffer& buffer)
{
uint64 numMeshes = 0;
Serialization::load(buffer, numMeshes);
meshes.resize(numMeshes);
for (auto& mesh : meshes)
{
PVertexShaderInput vertexInput = new StaticMeshVertexInput("");
vertexInput->load(buffer);
Array<uint8> rawIndices;
Serialization::load(buffer, rawIndices);
Gfx::SeIndexType indexType;
Serialization::load(buffer, indexType);
IndexBufferCreateInfo createInfo = {
.resourceData = {
.size = rawIndices.size(),
.data = rawIndices.data(),
},
.indexType = indexType,
};
Gfx::PIndexBuffer indexBuffer = buffer.getGraphics()->createIndexBuffer(createInfo);
mesh = new Mesh(vertexInput, indexBuffer);
std::string matname;
Serialization::load(buffer, matname);
mesh->referencedMaterial = AssetRegistry::findMaterial(matname);
}
}
void MeshAsset::addMesh(PMesh mesh)
{
std::scoped_lock lck(lock);
meshes.add(mesh);
referencedMaterials.add(mesh->referencedMaterial);
}
const Array<PMesh> MeshAsset::getMeshes()
{
std::scoped_lock lck(lock);
return meshes;
}
+4 -5
View File
@@ -9,16 +9,15 @@ DECLARE_REF(MaterialInterface)
class MeshAsset : public Asset
{
public:
static constexpr uint64 IDENTIFIER = 0x2;
MeshAsset();
MeshAsset(const std::string& directory, const std::string& name);
MeshAsset(const std::filesystem::path& fullPath);
MeshAsset(std::string_view folderPath, std::string_view name);
virtual ~MeshAsset();
virtual void save(Gfx::PGraphics graphics) override;
virtual void load(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
void addMesh(PMesh mesh);
const Array<PMesh> getMeshes();
//Workaround while no editor
Array<PMaterialInterface> referencedMaterials;
Array<PMesh> meshes;
Component::Collider physicsMesh;
};
+15 -16
View File
@@ -33,20 +33,20 @@ void MeshLoader::importAsset(MeshImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PMeshAsset asset = new MeshAsset(assetPath.generic_string());
PMeshAsset asset = new MeshAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerMesh(asset, args.importPath);
AssetRegistry::get().registerMesh(asset);
import(args, asset);
}
void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterial>& globalMaterials)
void MeshLoader::loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array<PMaterialAsset>& globalMaterials)
{
using json = nlohmann::json;
for(uint32 i = 0; i < scene->mNumMaterials; ++i)
{
aiMaterial* material = scene->mMaterials[i];
json matCode;
matCode["name"] = material->GetName().C_Str();
matCode["name"] = baseName + material->GetName().C_Str();
matCode["profile"] = "BlinnPhong"; //TODO: other shading models
aiString texPath;
//TODO make samplers based on used textures
@@ -89,18 +89,17 @@ void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterial>& globalMat
matCode["code"]["normal"] = "return normalTexture.Sample(textureSampler, input.texCoords[0]).xyz;";
}
std::string outMatFilename = matCode["name"].get<std::string>().append(".asset");
std::ofstream outMatFile = AssetRegistry::createWriteStream(outMatFilename);
std::ofstream outMatFile = std::ofstream(meshDirectory / outMatFilename);
outMatFile << std::setw(4) << matCode;
outMatFile.flush();
outMatFile.close();
std::cout << "writing json to " << outMatFilename << std::endl;
AssetRegistry::importMaterial(MaterialImportArgs{
.filePath = AssetRegistry::getRootFolder() + "/" + outMatFilename,
.importPath = "",
.filePath = meshDirectory / outMatFilename,
.importPath = importPath,
});
PMaterialAsset asset = AssetRegistry::findMaterial(matCode["name"].get<std::string>());
globalMaterials[i] = asset->getMaterial();
globalMaterials[i] = AssetRegistry::findMaterial(matCode["name"].get<std::string>());
}
}
@@ -168,7 +167,7 @@ VertexStreamComponent createVertexStream(uint32 size, aiColor4D* sourceData, Gfx
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT);
}
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterial>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider)
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialAsset>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider)
{
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
{
@@ -191,7 +190,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterial>&
{
if(mesh->HasTextureCoords(i))
{
data.textureCoordinates.add(createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics));
data.textureCoordinates[i] = createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics);
}
}
if(mesh->HasNormals())
@@ -243,7 +242,7 @@ void MeshLoader::convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numP
dst[i * 4 + 3] = src[i].a;
}
}
void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory)
void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath)
{
for (uint32 i = 0; i < scene->mNumTextures; ++i)
{
@@ -269,7 +268,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path&
std::cout << "Loading model texture " << texPngPath.string() << std::endl;
AssetRegistry::importTexture(TextureImportArgs {
.filePath = texPath,
.importPath = ""
.importPath = importPath,
});
}
}
@@ -288,9 +287,9 @@ void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset)
aiProcess_FindDegenerates));
const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
Array<PMaterial> globalMaterials(scene->mNumMaterials);
loadTextures(scene, args.filePath.parent_path());
loadMaterials(scene, globalMaterials);
Array<PMaterialAsset> globalMaterials(scene->mNumMaterials);
loadTextures(scene, args.filePath.parent_path(), args.importPath);
loadMaterials(scene, args.filePath.stem().string(), args.filePath.parent_path(), args.importPath, globalMaterials);
Array<PMesh> globalMeshes(scene->mNumMeshes);
Component::Collider collider;
+4 -4
View File
@@ -10,7 +10,7 @@ namespace Seele
{
DECLARE_REF(Mesh)
DECLARE_REF(MeshAsset)
DECLARE_REF(Material)
DECLARE_REF(MaterialAsset)
DECLARE_NAME_REF(Gfx, Graphics)
struct MeshImportArgs
{
@@ -24,9 +24,9 @@ public:
~MeshLoader();
void importAsset(MeshImportArgs args);
private:
void loadMaterials(const aiScene* scene, Array<PMaterial>& globalMaterials);
void loadTextures(const aiScene* scene, const std::filesystem::path& meshPath);
void loadGlobalMeshes(const aiScene* scene, const Array<PMaterial>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider);
void loadMaterials(const aiScene* scene, const std::string& baseName, const std::filesystem::path& meshDirectory, const std::string& importPath, Array<PMaterialAsset>& globalMaterials);
void loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath);
void loadGlobalMeshes(const aiScene* scene, const Array<PMaterialAsset>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider);
void convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels);
void import(MeshImportArgs args, PMeshAsset meshAsset);
+80 -31
View File
@@ -7,16 +7,14 @@
using namespace Seele;
#define KTX_CHECK(x) { ktx_error_code_e err = x; assert(err == KTX_SUCCESS); }
TextureAsset::TextureAsset()
{
}
TextureAsset::TextureAsset(const std::string& directory, const std::string& name)
: Asset(directory, name)
{
}
TextureAsset::TextureAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
TextureAsset::TextureAsset(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
@@ -25,48 +23,99 @@ TextureAsset::~TextureAsset()
}
void TextureAsset::save(Gfx::PGraphics graphics)
void TextureAsset::save(ArchiveBuffer& buffer) const
{
//TODO: make this an actual file, not just a png wrapper
assert(false && "Editing textures is not yet supported");
Array<uint8> textureData;
ktxTexture2* kTexture;
ktxTextureCreateInfo createInfo = {
.vkFormat = (uint32_t)texture->getFormat(),
.baseWidth = texture->getSizeX(),
.baseHeight = texture->getSizeY(),
.baseDepth = texture->getSizeZ(),
.numDimensions = texture->getSizeZ() > 1 ? 3u : texture->getSizeY() > 1 ? 2u : 1u,
.numLevels = texture->getMipLevels(),
.numLayers = 1,
.numFaces = texture->getNumFaces(),
.isArray = false,
.generateMipmaps = false,
};
KTX_CHECK(ktxTexture2_Create(&createInfo, KTX_TEXTURE_CREATE_ALLOC_STORAGE, &kTexture));
for (uint32 depth = 0; depth < texture->getSizeZ(); ++depth)
{
for (uint32 face = 0; face < texture->getNumFaces(); ++face)
{
// technically, downloading cant be const, because we have to allocate temporary buffers and change layouts
// but practically the texture stays the same
const_cast<Gfx::Texture*>(texture.getHandle())->download(0, depth, face, textureData);
KTX_CHECK(ktxTexture_SetImageFromMemory(ktxTexture(kTexture), 0, depth, face, textureData.data(), textureData.size()));
}
}
char writer[100];
snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1");
ktxHashList_AddKVPair(&kTexture->kvDataHead, KTX_WRITER_KEY,
(ktx_uint32_t)strlen(writer) + 1,
writer);
//ktx_error_code_e error = ktxTexture2_CompressBasis(kTexture, 0);
ktx_uint8_t* texData;
ktx_size_t texSize;
KTX_CHECK(ktxTexture_WriteToMemory(ktxTexture(kTexture), &texData, &texSize));
Array<uint8> rawData(texSize);
std::memcpy(rawData.data(), texData, texSize);
free(texData);
Serialization::save(buffer, rawData);
}
void TextureAsset::load(Gfx::PGraphics graphics)
void TextureAsset::load(ArchiveBuffer& buffer)
{
setStatus(Status::Loading);
ktxTexture2* kTexture;
// TODO: consider return
std::cout << "Loading texture " << getFullPath() << std::endl;
ktxTexture2_CreateFromNamedFile(getFullPath().c_str(),
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
&kTexture);
TextureCreateInfo createInfo;
createInfo.width = kTexture->baseWidth;
createInfo.height = kTexture->baseHeight;
createInfo.depth = kTexture->baseDepth;
createInfo.bArray = kTexture->isArray;
createInfo.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces;
createInfo.format = Vulkan::cast((VkFormat)kTexture->vkFormat);
createInfo.mipLevels = kTexture->numLevels;
createInfo.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
createInfo.resourceData.data = ktxTexture_GetData(ktxTexture(kTexture));
createInfo.resourceData.size = ktxTexture_GetDataSize(ktxTexture(kTexture));
createInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
Array<uint8> rawData;
Serialization::load(buffer, rawData);
ktxTexture2* kTexture;
std::cout << "Loading texture " << name << std::endl;
KTX_CHECK(ktxTexture_CreateFromMemory(rawData.data(),
rawData.size(),
KTX_TEXTURE_CREATE_LOAD_IMAGE_DATA_BIT,
(ktxTexture**) & kTexture));
//ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_BC7_RGBA, 0);
TextureCreateInfo createInfo = {
.resourceData = {
.size = ktxTexture_GetDataSize(ktxTexture(kTexture)),
.data = ktxTexture_GetData(ktxTexture(kTexture)),
.owner = Gfx::QueueType::DEDICATED_TRANSFER,
},
.width = kTexture->baseWidth,
.height = kTexture->baseHeight,
.depth = kTexture->baseDepth,
.bArray = kTexture->isArray,
.arrayLayers = kTexture->isArray ? kTexture->numLayers : kTexture->numFaces,
.mipLevels = kTexture->numLevels,
.format = Vulkan::cast((VkFormat)kTexture->vkFormat),
.usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT,
};
Gfx::PTexture tex;
if (kTexture->isCubemap)
{
tex = graphics->createTextureCube(createInfo);
tex = buffer.getGraphics()->createTextureCube(createInfo);
}
else if (kTexture->isArray)
{
tex = graphics->createTexture3D(createInfo);
tex = buffer.getGraphics()->createTexture3D(createInfo);
}
else
{
tex = graphics->createTexture2D(createInfo);
tex = buffer.getGraphics()->createTexture2D(createInfo);
}
tex->transferOwnership(Gfx::QueueType::GRAPHICS);
setTexture(tex);
ktxTexture_Destroy(ktxTexture(kTexture));
setStatus(Asset::Status::Ready);
}
+4 -6
View File
@@ -7,20 +7,18 @@ DECLARE_NAME_REF(Gfx, Texture)
class TextureAsset : public Asset
{
public:
static constexpr uint64 IDENTIFIER = 0x1;
TextureAsset();
TextureAsset(const std::string& directory, const std::string& name);
TextureAsset(const std::filesystem::path& fullPath);
TextureAsset(std::string_view folderPath, std::string_view name);
virtual ~TextureAsset();
virtual void save(Gfx::PGraphics graphics) override;
virtual void load(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
void setTexture(Gfx::PTexture _texture)
{
std::scoped_lock lck(lock);
texture = _texture;
}
Gfx::PTexture getTexture()
{
std::scoped_lock lck(lock);
return texture;
}
private:
+56 -22
View File
@@ -14,9 +14,15 @@ using namespace Seele;
TextureLoader::TextureLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
placeholderAsset = new TextureAsset(std::filesystem::absolute("./textures/placeholder.ktx"));
placeholderAsset->load(graphics);
AssetRegistry::get().assetRoot.textures[""] = placeholderAsset;
//(std::filesystem::absolute("./textures/placeholder.ktx"));
//placeholderAsset->load(graphics);
//AssetRegistry::get().assetRoot.textures[""] = placeholderAsset;
placeholderAsset = new TextureAsset();
import(TextureImportArgs{
.filePath = std::filesystem::absolute("./textures/placeholder.png"),
.importPath = "",
}, placeholderAsset);
AssetRegistry::get().assetRoot->textures[""] = placeholderAsset;
}
TextureLoader::~TextureLoader()
@@ -27,10 +33,10 @@ void TextureLoader::importAsset(TextureImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PTextureAsset asset = new TextureAsset(assetPath.generic_string());
PTextureAsset asset = new TextureAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
asset->setTexture(placeholderAsset->getTexture());
AssetRegistry::get().registerTexture(asset, args.importPath);
AssetRegistry::get().registerTexture(asset);
import(args, asset);
}
@@ -45,22 +51,22 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset)
unsigned char* data = stbi_load(args.filePath.string().c_str(), &totalWidth, &totalHeight, &n, 4);
ktxTexture2* kTexture;
ktxTextureCreateInfo createInfo;
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_UNORM;
createInfo.baseDepth = 1;
createInfo.numLevels = 1;
createInfo.numLayers = 1;
createInfo.isArray = false;
createInfo.generateMipmaps = false;
if (args.type == TextureImportType::TEXTURE_CUBEMAP)
{
uint32 faceWidth = totalWidth / 4;
uint32 faceHeight = totalHeight / 3;
// Cube map
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB;
createInfo.baseWidth = totalWidth / 4;
createInfo.baseHeight = totalHeight / 3;
createInfo.baseDepth = 1;
createInfo.numFaces = 6;
createInfo.numDimensions = 2;
createInfo.numLevels = 1;
createInfo.numLayers = 1;
createInfo.isArray = false;
createInfo.generateMipmaps = true;
ktxTexture2_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
@@ -85,21 +91,15 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset)
loadCubeFace(0, 1, 1); // -X
loadCubeFace(1, 0, 2); // +Y
loadCubeFace(1, 2, 3); // -Y
loadCubeFace(1, 1, 4); // -Z
loadCubeFace(1, 1, 4); // +Z
loadCubeFace(3, 1, 5); // -Z
}
else
{
createInfo.vkFormat = VK_FORMAT_R8G8B8A8_SRGB;
createInfo.baseWidth = totalWidth;
createInfo.baseHeight = totalHeight;
createInfo.baseDepth = 1;
createInfo.numDimensions = 1 + (totalHeight > 1);
createInfo.numLevels = 1;
createInfo.numLayers = 1;
createInfo.numFaces = 1;
createInfo.isArray = false;
createInfo.generateMipmaps = true;
createInfo.numDimensions = 1 + (totalHeight > 1);
ktxTexture2_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
@@ -108,13 +108,47 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset)
ktxTexture_SetImageFromMemory(ktxTexture(kTexture),
0, 0, 0, data, totalWidth * totalHeight * 4 * sizeof(unsigned char));
}
std::cout << "starting compression of " << textureAsset->getAssetIdentifier() << std::endl;
ktxBasisParams params = {
.structSize = sizeof(ktxBasisParams),
.uastc = KTX_TRUE,
.threadCount = std::thread::hardware_concurrency(),
.qualityLevel = 0,
};
//ktx_error_code_e error = ktxTexture2_CompressBasisEx(kTexture, &params);
//assert(error == KTX_SUCCESS);
//error = ktxTexture2_TranscodeBasis(kTexture, KTX_TTF_BC7_RGBA, 0);
//assert(error == KTX_SUCCESS);
stbi_image_free(data);
ktxTexture_WriteToNamedFile(ktxTexture(kTexture), textureAsset->getFullPath().c_str());
ktxTexture_Destroy(ktxTexture(kTexture));
TextureCreateInfo texInfo = {
.resourceData = {
.size = ktxTexture_GetDataSize(ktxTexture(kTexture)),
.data = ktxTexture_GetData(ktxTexture(kTexture)),
},
.width = createInfo.baseWidth,
.height = createInfo.baseHeight,
.depth = createInfo.baseDepth,
.bArray = false,
.arrayLayers = createInfo.numFaces,
.mipLevels = 1,
.samples = 1,
.format = (Gfx::SeFormat)kTexture->vkFormat,
.usage = args.usage,
};
textureAsset->load(graphics);
if (createInfo.numFaces == 1)
{
textureAsset->setTexture(graphics->createTexture2D(texInfo));
}
else
{
textureAsset->setTexture(graphics->createTextureCube(texInfo));
}
ktxTexture_Destroy(ktxTexture(kTexture));
textureAsset->setStatus(Asset::Status::Ready);
////co_return;
}
+2
View File
@@ -1,6 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include "Graphics/GraphicsEnums.h"
#include <filesystem>
namespace Seele
@@ -18,6 +19,7 @@ struct TextureImportArgs
std::filesystem::path filePath;
std::string importPath;
TextureImportType type = TextureImportType::TEXTURE_2D;
Gfx::SeImageUsageFlagBits usage = Gfx::SE_IMAGE_USAGE_SAMPLED_BIT;
};
class TextureLoader
{
+3
View File
@@ -1,5 +1,6 @@
target_sources(Engine
PRIVATE
Concepts.h
EngineTypes.h
Game.h
MinimalEngine.h
@@ -8,6 +9,7 @@ target_sources(Engine
target_sources(Engine
PUBLIC FILE_SET HEADERS
FILES
Concepts.h
Game.h
EngineTypes.h
MinimalEngine.h)
@@ -20,6 +22,7 @@ add_subdirectory(Graphics/)
add_subdirectory(Material/)
add_subdirectory(Math/)
add_subdirectory(Physics/)
add_subdirectory(Serialization/)
add_subdirectory(Scene/)
add_subdirectory(System/)
add_subdirectory(UI/)
+9
View File
@@ -5,4 +5,13 @@ namespace Seele
{
template<class F, class... Args>
concept invocable = std::invocable<F, Args...>;
template<class T, class Archive>
concept serializable = requires(T t, Archive& a)
{
t->save(a);
t->load(a);
};
template<typename T>
concept enumeration = std::is_enum_v<T>;
}
+2 -2
View File
@@ -34,7 +34,7 @@ public:
: node(i.node)
{
}
IteratorBase(IteratorBase&& i)
IteratorBase(IteratorBase&& i) noexcept
: node(std::move(i.node))
{
}
@@ -49,7 +49,7 @@ public:
}
return *this;
}
IteratorBase& operator=(IteratorBase&& other)
IteratorBase& operator=(IteratorBase&& other) noexcept
{
if(this != &other)
{
+41 -18
View File
@@ -250,9 +250,7 @@ public:
constexpr mapped_type& operator[](const key_type& key)
{
root = splay(root, key);
if (!isValid(root)
|| comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key))
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
root = insert(root, key);
_size++;
@@ -263,9 +261,7 @@ public:
constexpr mapped_type& operator[](key_type&& key)
{
root = splay(root, std::move(key));
if (!isValid(root)
|| comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key))
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
root = insert(root, std::move(key));
_size++;
@@ -273,13 +269,32 @@ public:
markIteratorsDirty();
return getNode(root)->pair.value;
}
constexpr mapped_type& at(const key_type& key)
{
root = splay(root, key);
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
throw std::logic_error("Key not found");
}
markIteratorsDirty();
return getNode(root)->pair.value;
}
constexpr mapped_type& at(key_type&& key)
{
root = splay(root, std::move(key));
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
throw std::logic_error("Key not found");
}
markIteratorsDirty();
return getNode(root)->pair.value;
}
constexpr iterator find(const key_type& key)
{
root = splay(root, key);
refreshIterators();
if (!isValid(root)
|| comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key))
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
return endIt;
}
@@ -289,9 +304,7 @@ public:
{
root = splay(root, std::move(key));
refreshIterators();
if (!isValid(root)
|| comp(getNode(root)->pair.key, key)
|| comp(key, getNode(root)->pair.key))
if (!isValid(root) || !equal(getNode(root)->pair.key, key))
{
return endIt;
}
@@ -324,6 +337,14 @@ public:
{
return find(std::move(key)) != endIt;
}
constexpr bool contains(const key_type& key)
{
return exists(key);
}
constexpr bool contains(key_type&& key)
{
return exists(key);
}
constexpr iterator begin()
{
if(iteratorsDirty)
@@ -476,13 +497,13 @@ private:
r = splay(r, key);
Node* node = getNode(r);
if (!(comp(node->pair.key, key) || comp(key, node->pair.key)))
if (equal(node->pair.key, key))
return r;
Node *newNode = &nodeContainer.emplace(std::forward<KeyType>(key));
node = getNode(r);
if (comp(key, node->pair.key))
if (comp(newNode->pair.key, node->pair.key))
{
newNode->rightChild = r;
newNode->leftChild = node->leftChild;
@@ -506,7 +527,7 @@ private:
r = splay(r, key);
Node* node = getNode(r);
if (comp(node->pair.key, key) || comp(key, node->pair.key))
if (!equal(node->pair.key, key))
return r;
if (!isValid(node->leftChild))
@@ -549,9 +570,7 @@ private:
size_t splay(size_t r, KeyType&& key)
{
Node* node = getNode(r);
if (node == nullptr
|| !(comp(node->pair.key, key)
|| comp(key, node->pair.key)))
if (node == nullptr || equal(node->pair.key, key))
{
return r;
}
@@ -602,5 +621,9 @@ private:
return (!isValid(node->rightChild)) ? r : rotateLeft(r);
}
}
bool equal(const key_type& a, const key_type& b)
{
return !comp(a, b) && !comp(b, a);
}
};
} // namespace Seele
-1
View File
@@ -10,7 +10,6 @@ class Game
public:
Game(AssetRegistry* registry) {}
virtual ~Game() {}
virtual void importAssets() = 0;
virtual void setupScene(PScene scene, PSystemGraph graph) = 0;
};
} // namespace Seele
-3
View File
@@ -12,8 +12,6 @@ target_sources(Engine
Mesh.cpp
MeshBatch.h
MeshBatch.cpp
RenderMaterial.h
RenderMaterial.cpp
ShaderCompiler.h
ShaderCompiler.cpp
VertexShaderInput.h
@@ -31,7 +29,6 @@ target_sources(Engine
Graphics.h
Mesh.h
MeshBatch.h
RenderMaterial.h
ShaderCompiler.h
VertexShaderInput.h
StaticMeshVertexInput.h)
+111
View File
@@ -1,6 +1,117 @@
#include "GraphicsEnums.h"
using namespace Seele;
using namespace Seele::Gfx;
uint32 Gfx::currentFrameIndex = 0;
double Gfx::currentFrameDelta = 0;
FormatCompatibilityInfo Gfx::getFormatInfo(SeFormat format)
{
switch(format) {
case SE_FORMAT_R4G4_UNORM_PACK8:
case SE_FORMAT_R8_UNORM:
case SE_FORMAT_R8_SNORM:
case SE_FORMAT_R8_USCALED:
case SE_FORMAT_R8_SSCALED:
case SE_FORMAT_R8_UINT:
case SE_FORMAT_R8_SINT:
case SE_FORMAT_R8_SRGB:
return FormatCompatibilityInfo {
.blockSize = 1,
.blockExtent = UVector(1, 1, 1),
.texelsPerBlock = 1,
};
case SE_FORMAT_R10X6_UNORM_PACK16:
case SE_FORMAT_R12X4_UNORM_PACK16:
//case SE_FORMAT_A4R4G4B4_UNORM_PACK16:
//case SE_FORMAT_A4B4G4R4_UNORM_PACK16:
case SE_FORMAT_R4G4B4A4_UNORM_PACK16:
case SE_FORMAT_B4G4R4A4_UNORM_PACK16:
case SE_FORMAT_R5G6B5_UNORM_PACK16:
case SE_FORMAT_B5G6R5_UNORM_PACK16:
case SE_FORMAT_R5G5B5A1_UNORM_PACK16:
case SE_FORMAT_B5G5R5A1_UNORM_PACK16:
case SE_FORMAT_A1R5G5B5_UNORM_PACK16:
case SE_FORMAT_R8G8_UNORM:
case SE_FORMAT_R8G8_SNORM:
case SE_FORMAT_R8G8_USCALED:
case SE_FORMAT_R8G8_SSCALED:
case SE_FORMAT_R8G8_UINT:
case SE_FORMAT_R8G8_SINT:
case SE_FORMAT_R8G8_SRGB:
case SE_FORMAT_R16_UNORM:
case SE_FORMAT_R16_SNORM:
case SE_FORMAT_R16_USCALED:
case SE_FORMAT_R16_SSCALED:
case SE_FORMAT_R16_UINT:
case SE_FORMAT_R16_SINT:
case SE_FORMAT_R16_SFLOAT:
return FormatCompatibilityInfo {
.blockSize = 2,
.blockExtent = UVector(1, 1, 1),
.texelsPerBlock = 1,
};
case SE_FORMAT_BC7_UNORM_BLOCK:
case SE_FORMAT_BC7_SRGB_BLOCK:
return FormatCompatibilityInfo {
.blockSize = 16,
.blockExtent = UVector(4, 4, 1),
.texelsPerBlock = 16,
};
case SE_FORMAT_R10X6G10X6_UNORM_2PACK16:
case SE_FORMAT_R12X4G12X4_UNORM_2PACK16:
//case SE_FORMAT_R16G16_S10_5_NV:
case SE_FORMAT_R8G8B8A8_UNORM:
case SE_FORMAT_R8G8B8A8_SNORM:
case SE_FORMAT_R8G8B8A8_USCALED:
case SE_FORMAT_R8G8B8A8_SSCALED:
case SE_FORMAT_R8G8B8A8_UINT:
case SE_FORMAT_R8G8B8A8_SINT:
case SE_FORMAT_R8G8B8A8_SRGB:
case SE_FORMAT_B8G8R8A8_UNORM:
case SE_FORMAT_B8G8R8A8_SNORM:
case SE_FORMAT_B8G8R8A8_USCALED:
case SE_FORMAT_B8G8R8A8_SSCALED:
case SE_FORMAT_B8G8R8A8_UINT:
case SE_FORMAT_B8G8R8A8_SINT:
case SE_FORMAT_B8G8R8A8_SRGB:
case SE_FORMAT_A8B8G8R8_UNORM_PACK32:
case SE_FORMAT_A8B8G8R8_SNORM_PACK32:
case SE_FORMAT_A8B8G8R8_USCALED_PACK32:
case SE_FORMAT_A8B8G8R8_SSCALED_PACK32:
case SE_FORMAT_A8B8G8R8_UINT_PACK32:
case SE_FORMAT_A8B8G8R8_SINT_PACK32:
case SE_FORMAT_A8B8G8R8_SRGB_PACK32:
case SE_FORMAT_A2R10G10B10_UNORM_PACK32:
case SE_FORMAT_A2R10G10B10_SNORM_PACK32:
case SE_FORMAT_A2R10G10B10_USCALED_PACK32:
case SE_FORMAT_A2R10G10B10_SSCALED_PACK32:
case SE_FORMAT_A2R10G10B10_UINT_PACK32:
case SE_FORMAT_A2R10G10B10_SINT_PACK32:
case SE_FORMAT_A2B10G10R10_UNORM_PACK32:
case SE_FORMAT_A2B10G10R10_SNORM_PACK32:
case SE_FORMAT_A2B10G10R10_USCALED_PACK32:
case SE_FORMAT_A2B10G10R10_SSCALED_PACK32:
case SE_FORMAT_A2B10G10R10_UINT_PACK32:
case SE_FORMAT_A2B10G10R10_SINT_PACK32:
case SE_FORMAT_R16G16_UNORM:
case SE_FORMAT_R16G16_SNORM:
case SE_FORMAT_R16G16_USCALED:
case SE_FORMAT_R16G16_SSCALED:
case SE_FORMAT_R16G16_UINT:
case SE_FORMAT_R16G16_SINT:
case SE_FORMAT_R16G16_SFLOAT:
case SE_FORMAT_R32_UINT:
case SE_FORMAT_R32_SINT:
case SE_FORMAT_R32_SFLOAT:
case SE_FORMAT_B10G11R11_UFLOAT_PACK32:
case SE_FORMAT_E5B9G9R9_UFLOAT_PACK32:
return FormatCompatibilityInfo{
.blockSize = 4,
.blockExtent = Vector(1, 1, 1),
.texelsPerBlock = 1,
};
}
throw new std::logic_error("not yet implemented");
}
+11
View File
@@ -1,5 +1,6 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Vector.h"
namespace Seele
{
@@ -1003,6 +1004,16 @@ typedef enum SeFormat
SE_FORMAT_MAX_ENUM = 0x7FFFFFFF
} SeFormat;
struct FormatCompatibilityInfo
{
// std::string class
uint32 blockSize;
UVector blockExtent;
uint32 texelsPerBlock;
};
FormatCompatibilityInfo getFormatInfo(SeFormat format);
typedef enum SeImageType
{
SE_IMAGE_TYPE_1D = 0,
+1 -1
View File
@@ -1,9 +1,9 @@
#pragma once
#include "GraphicsEnums.h"
#include "Containers/Map.h"
namespace Seele
{
struct GraphicsInitializer
{
const char *applicationName;
+2 -1
View File
@@ -94,7 +94,7 @@ ShaderCollection& ShaderMap::createShaders(
return collection;
}
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags)
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount, SeDescriptorBindingFlags bindingFlags, SeShaderStageFlags shaderStages)
{
if (descriptorBindings.size() <= bindingIndex)
{
@@ -105,6 +105,7 @@ void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorTyp
binding.descriptorType = type;
binding.descriptorCount = arrayCount;
binding.bindingFlags = bindingFlags;
binding.shaderStages = shaderStages;
}
PDescriptorSet DescriptorLayout::allocateDescriptorSet()
+11 -5
View File
@@ -1,4 +1,5 @@
#pragma once
#include "Math/Math.h"
#include "GraphicsEnums.h"
#include "Containers/Array.h"
#include "Containers/List.h"
@@ -158,9 +159,9 @@ public:
: binding(other.binding), descriptorType(other.descriptorType), descriptorCount(other.descriptorCount), shaderStages(other.shaderStages)
{
}
uint32_t binding;
uint32 binding;
SeDescriptorType descriptorType;
uint32_t descriptorCount;
uint32 descriptorCount;
SeDescriptorBindingFlags bindingFlags = 0;
SeShaderStageFlags shaderStages;
};
@@ -217,11 +218,12 @@ public:
return *this;
}
virtual void create() = 0;
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0);
virtual void addDescriptorBinding(uint32 binding, SeDescriptorType type, uint32 arrayCount = 1, SeDescriptorBindingFlags bindingFlags = 0, SeShaderStageFlags shaderStages = SeShaderStageFlagBits::SE_SHADER_STAGE_ALL);
virtual void reset();
virtual PDescriptorSet allocateDescriptorSet();
const Array<DescriptorBinding> &getBindings() const { return descriptorBindings; }
inline uint32 getSetIndex() const { return setIndex; }
constexpr uint32 getSetIndex() const { return setIndex; }
constexpr void setSetIndex(uint32 _setIndex) { setIndex = _setIndex; }
protected:
Array<DescriptorBinding> descriptorBindings;
@@ -371,7 +373,7 @@ public:
}
virtual void updateRegion(BulkResourceData update) = 0;
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
@@ -396,6 +398,7 @@ public:
return indexType;
}
virtual void download(Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
@@ -543,6 +546,7 @@ public:
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 1; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
@@ -550,6 +554,7 @@ public:
virtual class Texture3D* getTexture3D() { return nullptr; }
virtual class TextureCube* getTextureCube() { return nullptr; }
virtual void* getNativeHandle() { return nullptr; }
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) = 0;
protected:
// Inherited via QueueOwnedResource
virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
@@ -612,6 +617,7 @@ public:
virtual uint32 getSizeX() const = 0;
virtual uint32 getSizeY() const = 0;
virtual uint32 getSizeZ() const = 0;
virtual uint32 getNumFaces() const { return 6; }
virtual SeSampleCountFlags getNumSamples() const = 0;
virtual uint32 getMipLevels() const = 0;
virtual void changeLayout(SeImageLayout newLayout) = 0;
+1
View File
@@ -1,5 +1,6 @@
#include "Mesh.h"
#include "VertexShaderInput.h"
#include "Graphics/Graphics.h"
using namespace Seele;
+2 -2
View File
@@ -1,6 +1,6 @@
#pragma once
#include "GraphicsResources.h"
#include "Material/MaterialInterface.h"
#include "Asset/MaterialAsset.h"
namespace Seele
{
@@ -14,7 +14,7 @@ public:
Gfx::PIndexBuffer indexBuffer;
PVertexShaderInput vertexInput;
PMaterialInterface referencedMaterial;
PMaterialAsset referencedMaterial;
private:
};
DEFINE_REF(Mesh)
+1
View File
@@ -2,6 +2,7 @@
#include "GraphicsResources.h"
#include "VertexShaderInput.h"
#include "Material/MaterialInterface.h"
#include "Graphics/Graphics.h"
using namespace Seele;
+1 -4
View File
@@ -1,5 +1,6 @@
#pragma once
#include "GraphicsEnums.h"
#include "Containers/Array.h"
namespace Seele
{
@@ -47,8 +48,4 @@ struct MeshBatch
MeshBatch& operator=(const MeshBatch& other) = default;
MeshBatch& operator=(MeshBatch&& other) = default;
};
struct StaticMeshBatch : public MeshBatch
{
uint32 index;
};
} // namespace Seele
-4
View File
@@ -1,4 +0,0 @@
#include "RenderMaterial.h"
using namespace Seele;
using namespace Seele::Gfx;
-44
View File
@@ -1,44 +0,0 @@
#pragma once
#include "GraphicsResources.h"
namespace Seele
{
namespace Gfx
{
class MaterialShaderMap;//TODO implement
class MaterialRenderContext;
struct UniformExpressionCache
{
Gfx::PUniformBuffer uniformBuffer;
uint8 bUpToDate;
const MaterialShaderMap* cachedUniformExpressionShaderMap;
};
class Material;
class RenderMaterial
{
public:
mutable UniformExpressionCache uniformExpressionCache;
RenderMaterial();
virtual ~RenderMaterial();
void evaluateUniformExpressions(UniformExpressionCache& outUniforExpressionCache, const MaterialRenderContext& context);
void cacheUniformExpressions(bool bRecreatueUniformBuffer);
void invalidateUniformExpressionCache(bool bRecreateUniformBuffer);
void updateUniformExpressionCacheIfNeeded() const;
const Material* getMaterial() const
{
const RenderMaterial* unused = nullptr;
return &getMaterialWithFallback(unused);
}
virtual const Material& getMaterialWithFallback(const RenderMaterial*& outFallbackRenderMaterial) const = 0;
virtual Material* getMaterialNoFallback() const { return nullptr; }
};
} // namespace Gfx
} // namespace Seele
+6 -1
View File
@@ -35,6 +35,11 @@ void BasePassMeshProcessor::processMeshBatch(
const PVertexShaderInput vertexInput = batch.vertexInput;
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
if(collection == nullptr)
{
material->createShaders(graphics, Gfx::RenderPassType::BasePass, vertexInput->getType());
collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
}
assert(collection != nullptr);
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
@@ -158,7 +163,7 @@ void BasePass::render()
descriptorSets[INDEX_LIGHT_ENV]->writeChanges();
graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : passData.staticDrawList)
for (const auto& meshBatch : passData.staticDrawList)
{
processor->processMeshBatch(meshBatch, viewport, renderPass, basePassLayout, primitiveLayout, descriptorSets);
}
+1 -1
View File
@@ -28,7 +28,7 @@ DEFINE_REF(BasePassMeshProcessor)
DECLARE_REF(CameraActor)
struct BasePassData
{
Array<StaticMeshBatch> staticDrawList;
Array<MeshBatch> staticDrawList;
Gfx::PStructuredBuffer sceneDataBuffer;
};
class BasePass : public RenderPass<BasePassData>
@@ -34,6 +34,11 @@ void DepthPrepassMeshProcessor::processMeshBatch(
const PVertexShaderInput vertexInput = batch.vertexInput;
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
if (collection == nullptr)
{
material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
}
assert(collection != nullptr);
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
@@ -128,7 +133,7 @@ void DepthPrepass::render()
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT);
depthAttachment->getTexture()->transferOwnership(Gfx::QueueType::GRAPHICS);
graphics->beginRenderPass(renderPass);
for (auto &&meshBatch : passData.staticDrawList)
for (const auto& meshBatch : passData.staticDrawList)
{
processor->processMeshBatch(meshBatch, viewport, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets);
}
@@ -25,7 +25,7 @@ private:
DEFINE_REF(DepthPrepassMeshProcessor)
struct DepthPrepassData
{
Array<StaticMeshBatch> staticDrawList;
Array<MeshBatch> staticDrawList;
Gfx::PStructuredBuffer sceneDataBuffer;
};
class DepthPrepass : public RenderPass<DepthPrepassData>
+21 -9
View File
@@ -47,16 +47,15 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics)
{
elements.add(accessStreamComponent(VertexStreamComponent(graphics->getNullVertexBuffer(), 0, 0, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), 4));
}
if(data.textureCoordinates.size())
const int32 baseTexCoordAttribute = 5;
for(uint32 coordinateIndex = 0; coordinateIndex < MAX_TEXCOORDS; ++coordinateIndex)
{
const int32 baseTexCoordAttribute = 5;
for(uint32 coordinateIndex = 0; coordinateIndex < data.textureCoordinates.size(); ++coordinateIndex)
{
elements.add(accessStreamComponent(
data.textureCoordinates[coordinateIndex],
static_cast<uint8>(baseTexCoordAttribute + coordinateIndex)
));
}
if (data.textureCoordinates[coordinateIndex].vertexBuffer == nullptr)
continue;
elements.add(accessStreamComponent(
data.textureCoordinates[coordinateIndex],
static_cast<uint8>(baseTexCoordAttribute + coordinateIndex)
));
}
initDeclaration(graphics, elements);
}
@@ -66,4 +65,17 @@ void StaticMeshVertexInput::setData(StaticMeshDataType&& _data)
data = std::move(_data);
}
void StaticMeshVertexInput::save(ArchiveBuffer& buffer)
{
Serialization::save(buffer, name);
Serialization::save(buffer, data);
}
void StaticMeshVertexInput::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, name);
Serialization::load(buffer, data);
init(buffer.getGraphics());
}
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput")
+31 -2
View File
@@ -10,7 +10,7 @@ struct StaticMeshDataType
VertexStreamComponent tangentBasisComponents[3];
//Dont forget these are 4 component vectors
Array<VertexStreamComponent> textureCoordinates;
VertexStreamComponent textureCoordinates[4];
VertexStreamComponent colorComponent;
};
@@ -21,9 +21,38 @@ public:
StaticMeshVertexInput(std::string name);
virtual ~StaticMeshVertexInput();
virtual void init(Gfx::PGraphics graphics) override;
virtual void save(ArchiveBuffer& buffer) override;
virtual void load(ArchiveBuffer& buffer) override;
void setData(StaticMeshDataType&& data);
private:
StaticMeshDataType data;
};
DEFINE_REF(StaticMeshVertexInput)
}
namespace Serialization
{
static void save(ArchiveBuffer& buffer, StaticMeshDataType& type)
{
Serialization::save(buffer, type.positionStream);
Serialization::save(buffer, type.tangentBasisComponents[0]);
Serialization::save(buffer, type.tangentBasisComponents[1]);
Serialization::save(buffer, type.tangentBasisComponents[2]);
Serialization::save(buffer, type.textureCoordinates[0]);
Serialization::save(buffer, type.textureCoordinates[1]);
Serialization::save(buffer, type.textureCoordinates[2]);
Serialization::save(buffer, type.textureCoordinates[3]);
Serialization::save(buffer, type.colorComponent);
}
static void load(ArchiveBuffer& buffer, StaticMeshDataType& type)
{
Serialization::load(buffer, type.positionStream);
Serialization::load(buffer, type.tangentBasisComponents[0]);
Serialization::load(buffer, type.tangentBasisComponents[1]);
Serialization::load(buffer, type.tangentBasisComponents[2]);
Serialization::load(buffer, type.textureCoordinates[0]);
Serialization::load(buffer, type.textureCoordinates[1]);
Serialization::load(buffer, type.textureCoordinates[2]);
Serialization::load(buffer, type.textureCoordinates[3]);
Serialization::load(buffer, type.colorComponent);
}
} // namespace Serialization
} // namespace Seele
+48 -2
View File
@@ -6,6 +6,54 @@
using namespace Seele;
void Seele::Serialization::save(ArchiveBuffer& buffer, VertexStreamComponent& comp)
{
if (comp.vertexBuffer == nullptr)
{
Serialization::save(buffer, (uint32)0);
}
else
{
Serialization::save(buffer, comp.vertexBuffer->getNumVertices());
Serialization::save(buffer, comp.vertexBuffer->getVertexSize());
Array<uint8> rawBuffer;
comp.vertexBuffer->download(rawBuffer);
Serialization::save(buffer, rawBuffer);
Serialization::save(buffer, comp.streamOffset);
Serialization::save(buffer, comp.offset);
Serialization::save(buffer, comp.stride);
Serialization::save(buffer, comp.type);
}
}
void Seele::Serialization::load(ArchiveBuffer& buffer, VertexStreamComponent& comp)
{
uint32 numVertices;
Serialization::load(buffer, numVertices);
if (numVertices == 0)
{
comp.vertexBuffer = nullptr;
}
else
{
uint32 vertexSize;
Serialization::load(buffer, vertexSize);
Array<uint8> rawBuffer;
Serialization::load(buffer, rawBuffer);
VertexBufferCreateInfo createInfo = {
.resourceData = {
.size = rawBuffer.size(),
.data = rawBuffer.data(),
},
.vertexSize = vertexSize,
.numVertices = numVertices,
};
comp.vertexBuffer = buffer.getGraphics()->createVertexBuffer(createInfo);
Serialization::load(buffer, comp.streamOffset);
Serialization::load(buffer, comp.offset);
Serialization::load(buffer, comp.stride);
Serialization::load(buffer, comp.type);
}
}
List<VertexInputType*>& VertexInputType::getTypeList()
{
@@ -90,7 +138,6 @@ Gfx::VertexElement VertexShaderInput::accessStreamComponent(const VertexStreamCo
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
vertexStream.stride = static_cast<uint8>(component.stride);
vertexStream.offset = static_cast<uint8>(component.offset);
@@ -101,7 +148,6 @@ Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const Vertex
{
VertexStream vertexStream;
vertexStream.vertexBuffer = component.vertexBuffer;
assert(component.stride < UINT8_MAX && component.offset < UINT8_MAX && component.offset < UINT8_MAX);
vertexStream.stride = static_cast<uint8>(component.stride);
vertexStream.offset = static_cast<uint8>(component.offset);
+8 -2
View File
@@ -2,6 +2,7 @@
#include "MinimalEngine.h"
#include "GraphicsEnums.h"
#include "GraphicsResources.h"
#include "Serialization/ArchiveBuffer.h"
namespace Seele
{
@@ -75,8 +76,11 @@ struct VertexStreamComponent
{}
};
#define STRUCTMEMBER_VERTEXSTREAMCOMPONENT(vertexBuffer, vertexType, member, memberType) \
VertexStreamComponent(vertexBuffer, offsetof(vertexType, member), sizeof(vertexType), memberType)
namespace Serialization
{
void save(ArchiveBuffer& buffer, VertexStreamComponent& comp);
void load(ArchiveBuffer& buffer, VertexStreamComponent& comp);
} // namespace Serialization
class VertexInputType
{
@@ -120,6 +124,8 @@ public:
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
virtual bool supportsTesselation() { return false; }
virtual VertexInputType* getType() const { return nullptr; }
virtual void save(ArchiveBuffer& buffer) {}
virtual void load(ArchiveBuffer& buffer) {}
Gfx::PVertexDeclaration getDeclaration() const {return declaration;}
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
std::string getName() const { return name; }
+13 -16
View File
@@ -182,7 +182,7 @@ void Allocation::markFree(SubAllocation *allocation)
if (allocHandle == nullptr)
{
allocHandle = new SubAllocation(this, allocation->alignedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
allocHandle = new SubAllocation(this, allocation->allocatedOffset, allocation->size, allocation->alignedOffset, allocation->allocatedSize);
freeRanges[allocation->allocatedOffset] = allocHandle;
}
activeAllocations.erase(allocation->allocatedOffset);
@@ -226,8 +226,7 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
{
std::scoped_lock lck(lock);
const VkMemoryRequirements &requirements = memRequirements2.memoryRequirements;
uint8 memoryTypeIndex;
VK_CHECK(findMemoryType(requirements.memoryTypeBits, properties, &memoryTypeIndex));
uint32 memoryTypeIndex = findMemoryType(requirements.memoryTypeBits, properties);
uint32 heapIndex = memProperties.memoryTypes[memoryTypeIndex].heapIndex;
if (memRequirements2.pNext != nullptr)
@@ -243,10 +242,13 @@ PSubAllocation Allocator::allocate(const VkMemoryRequirements2 &memRequirements2
}
for (auto alloc : heaps[heapIndex].allocations)
{
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
if (suballoc != nullptr)
if(alloc->memoryTypeIndex == memoryTypeIndex)
{
return suballoc;
PSubAllocation suballoc = alloc->getSuballocation(requirements.size, requirements.alignment);
if (suballoc != nullptr)
{
return suballoc;
}
}
}
@@ -273,22 +275,17 @@ void Allocator::free(Allocation *allocation)
}
}
}
VkResult Allocator::findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex)
uint32 Allocator::findMemoryType(uint32 typeFilter, VkMemoryPropertyFlags properties)
{
for (uint8 memoryIndex = 0; memoryIndex < memProperties.memoryTypeCount && typeBits; ++memoryIndex)
for (uint32 i = 0; i < memProperties.memoryTypeCount; i++)
{
if ((typeBits & 1) == 1)
if ((typeFilter & (1 << i)) && (memProperties.memoryTypes[i].propertyFlags & properties) == properties)
{
if ((memProperties.memoryTypes[memoryIndex].propertyFlags & properties) == properties)
{
*typeIndex = memoryIndex;
return VK_SUCCESS;
}
return i;
}
typeBits >>= 1;
}
return VK_ERROR_FORMAT_NOT_SUPPORTED;
throw std::runtime_error("error finding memory");
}
StagingBuffer::StagingBuffer()
+1 -1
View File
@@ -155,7 +155,7 @@ private:
Array<PAllocation> allocations;
};
Array<HeapInfo> heaps;
VkResult findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties, uint8 *typeIndex);
uint32 findMemoryType(uint32 typeBits, VkMemoryPropertyFlags properties);
std::mutex lock;
PGraphics graphics;
VkPhysicalDeviceMemoryProperties memProperties;
+15 -1
View File
@@ -208,7 +208,6 @@ void *ShaderBuffer::lockRegion(uint64 regionOffset, uint64 regionSize, bool bWri
else
{
PCmdBuffer current = graphics->getQueueCommands(owner)->getCommands();
graphics->getQueueCommands(owner)->submitCommands();
current->waitForCommand();
requestOwnershipTransfer(Gfx::QueueType::DEDICATED_TRANSFER);
@@ -466,6 +465,13 @@ void VertexBuffer::updateRegion(BulkResourceData update)
unlock();
}
void VertexBuffer::download(Array<uint8>& buffer)
{
void* data = lock(false);
buffer.resize(size);
std::memcpy(buffer.data(), data, size);
unlock();
}
void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
@@ -509,6 +515,14 @@ IndexBuffer::~IndexBuffer()
{
}
void IndexBuffer::download(Array<uint8>& buffer)
{
void* data = lock(false);
buffer.resize(size);
std::memcpy(buffer.data(), data, size);
unlock();
}
void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{
Gfx::QueueOwnedResource::transferOwnership(newOwner);
@@ -166,7 +166,12 @@ void CmdBuffer::refreshFence()
void CmdBuffer::waitForCommand(uint32 timeout)
{
std::scoped_lock lock(handleLock);
manager->submitCommands();
if (state == State::InsideBegin)
{
// is already done
return;
}
fence->wait(timeout);
refreshFence();
}
@@ -21,7 +21,6 @@ private:
PGraphics graphics;
Array<VkDescriptorSetLayoutBinding> bindings;
VkDescriptorSetLayout layoutHandle;
std::string name;
friend class DescriptorAllocator;
};
DEFINE_REF(DescriptorLayout)
@@ -501,7 +501,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
numQueuesForFamily++;
}
}
if ((currProps.queueFlags & VK_QUEUE_COMPUTE_BIT) == VK_QUEUE_COMPUTE_BIT)
if (currProps.queueFlags & VK_QUEUE_COMPUTE_BIT)
{
if (computeQueueInfo.familyIndex == -1)
{
@@ -526,7 +526,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
}
}
}
if ((currProps.queueFlags & VK_QUEUE_TRANSFER_BIT) == VK_QUEUE_TRANSFER_BIT)
if (currProps.queueFlags & VK_QUEUE_TRANSFER_BIT)
{
if (transferQueueInfo.familyIndex == -1)
{
@@ -587,6 +587,7 @@ void Graphics::createDevice(GraphicsInitializer initializer)
deviceInfo.ppEnabledExtensionNames = initializer.deviceExtensions.data();
deviceInfo.enabledLayerCount = (uint32_t)initializer.layers.size();
deviceInfo.ppEnabledLayerNames = initializer.layers.data();
deviceInfo.pEnabledFeatures = &features;
VK_CHECK(vkCreateDevice(physicalDevice, &deviceInfo, nullptr, &handle));
std::cout << "Vulkan handle: " << handle << std::endl;
@@ -68,7 +68,6 @@ public:
virtual Gfx::PPipelineLayout createPipelineLayout(Gfx::PPipelineLayout baseLayout = nullptr) override;
virtual void copyTexture(Gfx::PTexture srcTexture, Gfx::PTexture dstTexture) override;
protected:
Array<const char *> getRequiredExtensions();
void initInstance(GraphicsInitializer initInfo);
@@ -170,7 +170,7 @@ public:
virtual ~VertexBuffer();
virtual void updateRegion(BulkResourceData update) override;
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
@@ -189,6 +189,7 @@ public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
virtual ~IndexBuffer();
virtual void download(Array<uint8>& buffer) override;
protected:
// Inherited via Vulkan::Buffer
virtual VkAccessFlags getSourceAccessMask();
@@ -248,6 +249,7 @@ public:
void executePipelineBarrier(VkAccessFlags srcAccess, VkPipelineStageFlags srcStage,
VkAccessFlags dstAccess, VkPipelineStageFlags dstStage);
void changeLayout(Gfx::SeImageLayout newLayout);
void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer);
private:
//Updates via reference
@@ -314,6 +316,7 @@ public:
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
@@ -369,6 +372,7 @@ public:
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
@@ -424,6 +428,7 @@ public:
return textureHandle->getMipLevels();
}
virtual void changeLayout(Gfx::SeImageLayout newLayout) override;
virtual void download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer) override;
virtual void* getNativeHandle() override
{
return textureHandle;
+44 -1
View File
@@ -4,6 +4,7 @@
#include "VulkanGraphicsEnums.h"
#include "VulkanAllocator.h"
#include "VulkanCommandBuffer.h"
#include "Graphics/GraphicsEnums.h"
#include <math.h>
using namespace Seele;
@@ -127,7 +128,7 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
region.imageSubresource.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
region.imageSubresource.mipLevel = 0;
region.imageSubresource.baseArrayLayer = 0;
region.imageSubresource.layerCount = layerCount;
region.imageSubresource.layerCount = arrayCount * layerCount;
region.imageOffset = {0, 0, 0};
region.imageExtent = {sizeX, sizeY, sizeZ};
@@ -212,6 +213,35 @@ void TextureHandle::changeLayout(Gfx::SeImageLayout newLayout)
layout = newLayout;
}
void TextureHandle::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
uint64 imageSize = sizeX * sizeY * sizeZ * Gfx::getFormatInfo(format).blockSize;
PStagingBuffer stagingbuffer = graphics->getStagingManager()->allocateStagingBuffer(imageSize, VK_BUFFER_USAGE_TRANSFER_DST_BIT, true);
auto prevlayout = layout;
changeLayout(Gfx::SE_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
PCmdBuffer cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
Gfx::FormatCompatibilityInfo formatInfo = Gfx::getFormatInfo(format);
VkBufferImageCopy region = {
.bufferOffset = 0,
.bufferRowLength = 0,
.bufferImageHeight = 0,
.imageSubresource = {
.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
.mipLevel = mipLevel,
.baseArrayLayer = arrayLayer * layerCount + face,
.layerCount = 1,
},
.imageOffset = { 0, 0, 0 },
.imageExtent = { sizeX, sizeY, sizeZ },
};
vkCmdCopyImageToBuffer(cmdBuffer->getHandle(), image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, stagingbuffer->getHandle(), 1, &region);
changeLayout(prevlayout);
buffer.resize(stagingbuffer->getSize());
void* data = stagingbuffer->getMappedPointer();
std::memcpy(buffer.data(), data, buffer.size());
}
void TextureHandle::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
VkImageMemoryBarrier imageBarrier =
@@ -307,6 +337,11 @@ void Texture2D::changeLayout(Gfx::SeImageLayout newLayout)
textureHandle->changeLayout(newLayout);
}
void Texture2D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
}
void Texture2D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
@@ -334,6 +369,10 @@ void Texture3D::changeLayout(Gfx::SeImageLayout newLayout)
textureHandle->changeLayout(newLayout);
}
void Texture3D::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
}
void Texture3D::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
@@ -361,6 +400,10 @@ void TextureCube::changeLayout(Gfx::SeImageLayout newLayout)
textureHandle->changeLayout(newLayout);
}
void TextureCube::download(uint32 mipLevel, uint32 arrayLayer, uint32 face, Array<uint8>& buffer)
{
textureHandle->download(mipLevel, arrayLayer, face, buffer);
}
void TextureCube::executeOwnershipBarrier(Gfx::QueueType newOwner)
{
textureHandle->executeOwnershipBarrier(newOwner);
+48 -4
View File
@@ -40,9 +40,53 @@ Gfx::PDescriptorSet Material::createDescriptorSet()
return descriptorSet;
}
PMaterialInstance Material::instantiate()
void Material::save(ArchiveBuffer& buffer) const
{
return new MaterialInstance(graphics, this);
MaterialInterface::save(buffer);
Serialization::save(buffer,materialName);
Serialization::save(buffer, layout->getSetIndex());
const auto& bindings = layout->getBindings();
Serialization::save(buffer, bindings.size());
for (const auto& binding : bindings)
{
Serialization::save(buffer, binding.binding);
Serialization::save(buffer, binding.bindingFlags);
Serialization::save(buffer, binding.descriptorCount);
Serialization::save(buffer, binding.descriptorType);
Serialization::save(buffer, binding.shaderStages);
}
}
void Material::load(ArchiveBuffer& buffer)
{
graphics = buffer.getGraphics();
MaterialInterface::load(buffer);
Serialization::load(buffer, materialName);
uint32 setIndex;
Serialization::load(buffer, setIndex);
uint64 numBindings;
Serialization::load(buffer, numBindings);
layout = graphics->createDescriptorLayout();
for (uint64 i = 0; i < numBindings; ++i)
{
uint32 binding;
Serialization::load(buffer, binding);
Gfx::SeDescriptorBindingFlags bindingFlags;
Serialization::load(buffer, bindingFlags);
uint32 descriptorCount;
Serialization::load(buffer, descriptorCount);
Gfx::SeDescriptorType descriptorType;
Serialization::load(buffer, descriptorType);
Gfx::SeShaderStageFlags shaderStages;
Serialization::load(buffer, shaderStages);
layout->addDescriptorBinding(binding, descriptorType, descriptorCount, bindingFlags, shaderStages);
}
layout->create();
}
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
@@ -50,8 +94,8 @@ const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass
Gfx::ShaderPermutation permutation;
permutation.passType = renderPass;
std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
std::strncpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::strncpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
return shaderMap.findShaders(Gfx::PermutationId(permutation));
}
+4 -1
View File
@@ -7,13 +7,15 @@ DECLARE_REF(MaterialInstance)
class Material : public MaterialInterface
{
public:
Material() {}
Material(Gfx::PGraphics graphics, Array<PShaderParameter> parameter, Gfx::PDescriptorLayout layout, uint32 uniformDataSize, uint32 uniformBinding, std::string materialName);
virtual ~Material();
virtual Gfx::PDescriptorSet createDescriptorSet();
virtual Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
virtual const std::string& getName() { return materialName; }
PMaterialInstance instantiate();
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
virtual Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
@@ -29,4 +31,5 @@ private:
friend class MaterialInstance;
};
DEFINE_REF(Material)
} // namespace Seele
+40 -1
View File
@@ -27,9 +27,10 @@ MaterialInterface::~MaterialInterface()
{
}
PShaderParameter MaterialInterface::getParameter(const std::string& name)
{
for (auto param : parameters)
for (const auto& param : parameters)
{
if(param->name.compare(name) == 0)
{
@@ -38,3 +39,41 @@ PShaderParameter MaterialInterface::getParameter(const std::string& name)
}
return nullptr;
}
void MaterialInterface::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, uniformDataSize);
Serialization::save(buffer, uniformBinding);
uint64 length = parameters.size();
Serialization::save(buffer, length);
for (const auto& param : parameters)
{
Serialization::save(buffer, param);
}
}
void MaterialInterface::load(ArchiveBuffer& buffer)
{
graphics = buffer.getGraphics();
Serialization::load(buffer, uniformDataSize);
Serialization::load(buffer, uniformBinding);
if (uniformDataSize != 0)
{
uniformData.resize(uniformDataSize);
UniformBufferCreateInfo uniformInitializer = {
.resourceData = {
.size = uniformDataSize,
.data = nullptr,
}
};
uniformBuffer = graphics->createUniformBuffer(uniformInitializer);
}
uint64 length;
Serialization::load(buffer, length);
parameters.resize(length);
for (auto& param : parameters)
{
Serialization::load(buffer, param);
}
}
+4
View File
@@ -9,12 +9,16 @@ DECLARE_NAME_REF(Gfx, UniformBuffer)
class MaterialInterface
{
public:
MaterialInterface() {}
MaterialInterface(Gfx::PGraphics graphics, Array<PShaderParameter> parameter, uint32 uniformDataSize, uint32 uniformBinding);
virtual ~MaterialInterface();
PShaderParameter getParameter(const std::string& name);
virtual Gfx::PDescriptorSet createDescriptorSet() = 0;
virtual Gfx::PDescriptorLayout getDescriptorLayout() const = 0;
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
// The name of the generated material shader, opposed to the name of the .asset file
virtual const std::string& getName() = 0;
virtual const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const = 0;
+118
View File
@@ -1,6 +1,8 @@
#include "ShaderExpression.h"
#include "Graphics/GraphicsResources.h"
#include "Asset/TextureAsset.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/Graphics.h"
using namespace Seele;
@@ -15,8 +17,23 @@ ShaderParameter::~ShaderParameter()
{
}
void ShaderParameter::save(ArchiveBuffer& buffer) const
{
Serialization::save(buffer, name);
Serialization::save(buffer, byteOffset);
Serialization::save(buffer, binding);
}
void ShaderParameter::load(ArchiveBuffer& buffer)
{
Serialization::load(buffer, name);
Serialization::load(buffer, byteOffset);
Serialization::load(buffer, binding);
}
FloatParameter::FloatParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data(0)
{
}
@@ -24,6 +41,18 @@ FloatParameter::~FloatParameter()
{
}
void FloatParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void FloatParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(float));
@@ -31,6 +60,7 @@ void FloatParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
VectorParameter::VectorParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
, data()
{
}
@@ -38,11 +68,24 @@ VectorParameter::~VectorParameter()
{
}
void VectorParameter::updateDescriptorSet(Gfx::PDescriptorSet, uint8* dst)
{
std::memcpy(dst + byteOffset, &data, sizeof(Vector));
}
void VectorParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data);
}
void VectorParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
Serialization::load(buffer, data);
}
TextureParameter::TextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -57,6 +100,20 @@ void TextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
descriptorSet->updateTexture(binding, data->getTexture());
}
void TextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void TextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
}
SamplerParameter::SamplerParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -72,6 +129,18 @@ void SamplerParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, ui
descriptorSet->updateSampler(binding, data);
}
void SamplerParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
}
void SamplerParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
data = buffer.getGraphics()->createSamplerState({});
}
CombinedTextureParameter::CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding)
: ShaderParameter(name, byteOffset, binding)
{
@@ -82,7 +151,56 @@ CombinedTextureParameter::~CombinedTextureParameter()
}
void CombinedTextureParameter::updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8*)
{
descriptorSet->updateTexture(binding, data->getTexture(), sampler);
}
void CombinedTextureParameter::save(ArchiveBuffer& buffer) const
{
ShaderParameter::save(buffer);
Serialization::save(buffer, data->getAssetIdentifier());
}
void CombinedTextureParameter::load(ArchiveBuffer& buffer)
{
ShaderParameter::load(buffer);
std::string filename;
Serialization::load(buffer, filename);
data = AssetRegistry::findTexture(filename);
sampler = buffer.getGraphics()->createSamplerState({});
}
void Serialization::save(ArchiveBuffer& buffer, const PShaderParameter& parameter)
{
Serialization::save(buffer, parameter->getIdentifier());
parameter->save(buffer);
}
void Serialization::load(ArchiveBuffer& buffer, PShaderParameter& parameter)
{
uint64 identifier = 0;
Serialization::load(buffer, identifier);
switch (identifier)
{
case FloatParameter::IDENTIFIER:
parameter = new FloatParameter();
break;
case VectorParameter::IDENTIFIER:
parameter = new VectorParameter();
break;
case TextureParameter::IDENTIFIER:
parameter = new TextureParameter();
break;
case SamplerParameter::IDENTIFIER:
parameter = new SamplerParameter();
break;
case CombinedTextureParameter::IDENTIFIER:
parameter = new CombinedTextureParameter();
break;
default:
throw std::runtime_error("Unknown Identifier");
}
parameter->load(buffer);
}
+36 -1
View File
@@ -1,5 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "Math/Math.h"
#include "Asset/TextureAsset.h"
namespace Seele
{
@@ -20,53 +22,86 @@ struct ShaderParameter : public ShaderExpression
std::string name;
uint32 byteOffset;
uint32 binding;
ShaderParameter() {}
ShaderParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~ShaderParameter();
// update a descriptorset, in case of a uniform buffer, copy the data to the dst + byteOffset
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) = 0;
virtual uint64 getIdentifier() const = 0;
virtual void save(ArchiveBuffer& buffer) const;
virtual void load(ArchiveBuffer& buffer);
};
DEFINE_REF(ShaderParameter)
struct FloatParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x01;
float data;
FloatParameter() {}
FloatParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~FloatParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(FloatParameter)
struct VectorParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x02;
Vector data;
VectorParameter() {}
VectorParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~VectorParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(VectorParameter)
DECLARE_REF(TextureAsset)
struct TextureParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x04;
PTextureAsset data;
TextureParameter() {}
TextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~TextureParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(TextureParameter)
DECLARE_NAME_REF(Gfx, SamplerState)
struct SamplerParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x08;
Gfx::PSamplerState data;
SamplerParameter() {}
SamplerParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~SamplerParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(SamplerParameter)
struct CombinedTextureParameter : public ShaderParameter
{
static constexpr uint64 IDENTIFIER = 0x10;
PTextureAsset data;
Gfx::PSamplerState sampler;
CombinedTextureParameter() {}
CombinedTextureParameter(std::string name, uint32 byteOffset, uint32 binding);
virtual ~CombinedTextureParameter();
virtual void updateDescriptorSet(Gfx::PDescriptorSet descriptorSet, uint8* dst) override;
virtual uint64 getIdentifier() const override { return IDENTIFIER; }
virtual void save(ArchiveBuffer& buffer) const override;
virtual void load(ArchiveBuffer& buffer) override;
};
DEFINE_REF(CombinedTextureParameter)
namespace Serialization
{
void save(ArchiveBuffer& buffer, const PShaderParameter& parameter);
void load(ArchiveBuffer& buffer, PShaderParameter& parameter);
} // namespace Serialization
} // namespace Seele
+1
View File
@@ -2,6 +2,7 @@
#include <regex>
#include <format>
#include <nlohmann/json.hpp>
#include "Serialization/ArchiveBuffer.h"
using namespace Seele;
+30 -2
View File
@@ -8,6 +8,8 @@
#include <glm/gtc/quaternion.hpp>
#pragma warning(pop)
#include <nlohmann/json_fwd.hpp>
#include "Serialization/ArchiveBuffer.h"
namespace Seele
{
typedef glm::vec2 Vector2;
@@ -15,11 +17,11 @@ typedef glm::vec3 Vector;
typedef glm::vec4 Vector4;
typedef glm::uvec2 UVector2;
typedef glm::uvec3 UVector3;
typedef glm::uvec3 UVector;
typedef glm::uvec4 UVector4;
typedef glm::ivec2 IVector2;
typedef glm::ivec3 IVector3;
typedef glm::ivec3 IVector;
typedef glm::ivec4 IVector4;
typedef glm::quat Quaternion;
@@ -97,6 +99,32 @@ static inline Vector toRotator(const Quaternion &other)
}
void to_json(nlohmann::json& j, const Vector& vec);
void from_json(nlohmann::json& j, Vector& vec);
namespace Serialization
{
static void save(ArchiveBuffer& buffer, const IVector2& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
}
static void load(ArchiveBuffer& buffer, IVector2& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
}
static void save(ArchiveBuffer& buffer, const Vector& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
save(buffer, vec.z);
}
static void load(ArchiveBuffer& buffer, Vector& vec)
{
save(buffer, vec.x);
save(buffer, vec.y);
save(buffer, vec.z);
}
} // namespace Serialization
} // namespace Seele
std::ostream& operator<<(std::ostream& stream, const Seele::Vector2& vector);
+1 -4
View File
@@ -1,7 +1,5 @@
#pragma once
#include "Containers/Map.h"
#include "EngineTypes.h"
#include "Math/Math.h"
#include <map>
#define DEFINE_REF(x) \
@@ -206,7 +204,7 @@ public:
}
return *this;
}
constexpr RefPtr &operator=(RefPtr &&rhs)
constexpr RefPtr &operator=(RefPtr &&rhs) noexcept
{
if (this != &rhs)
{
@@ -260,7 +258,6 @@ public:
{
return RefPtr<T, Deleter>(new T(*getHandle()));
}
private:
RefObject<T, Deleter> *object;
};
+1 -1
View File
@@ -22,7 +22,7 @@ void PhysicsSystem::update(float deltaTime)
Array<Body> initialBodies;
readRigidBodies(initialBodies);
std::cout << "Updating " << initialBodies.size() << " bodies" << std::endl;
//std::cout << "Updating " << initialBodies.size() << " bodies" << std::endl;
Array<Body> bodies = integratePhysics(initialBodies, 0, deltaTime);
writeRigidBodies(bodies);
+4 -3
View File
@@ -5,6 +5,7 @@
#include "Component/Transform.h"
#include "Asset/AssetRegistry.h"
#include "Asset/TextureAsset.h"
#include "Asset/MaterialAsset.h"
using namespace Seele;
@@ -28,9 +29,9 @@ void Scene::update(float deltaTime)
physics.update(deltaTime);
}
Array<StaticMeshBatch> Scene::getStaticMeshes()
Array<MeshBatch> Scene::getStaticMeshes()
{
Array<StaticMeshBatch> result;
Array<MeshBatch> result;
auto view = registry.view<Component::StaticMesh, Component::Transform>();
uint32 sceneDataIndex = 0;
sceneData.clear();
@@ -44,7 +45,7 @@ Array<StaticMeshBatch> Scene::getStaticMeshes()
for(auto& m : mesh.mesh->meshes)
{
auto& batch = result.add();
batch.material = m->referencedMaterial;
batch.material = m->referencedMaterial->getMaterial();
batch.isBackfaceCullingDisabled = false;
batch.isCastingShadow = true;
batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
+1 -1
View File
@@ -69,7 +69,7 @@ public:
{
registry.view<Component>().each(func);
}
Array<StaticMeshBatch> getStaticMeshes();
Array<MeshBatch> getStaticMeshes();
LightEnv getLightBuffer() const;
Component::Skybox getSkybox();
Gfx::PStructuredBuffer getSceneDataBuffer() const { return sceneDataBuffer; }
@@ -0,0 +1,60 @@
#include "ArchiveBuffer.h"
#include "Graphics/Graphics.h"
using namespace Seele;
ArchiveBuffer::ArchiveBuffer()
{}
ArchiveBuffer::ArchiveBuffer(Gfx::PGraphics graphics)
: graphics(graphics)
{}
void ArchiveBuffer::writeBytes(const void* data, uint64 size)
{
if (size + position >= memory.size())
{
memory.resize(size + position);
}
std::memcpy(memory.data() + position, data, size);
position += size;
}
void ArchiveBuffer::readBytes(void* dest, uint64 size)
{
assert(position + size <= memory.size());
std::memcpy(dest, memory.data() + position, size);
position += size;
}
void ArchiveBuffer::writeToStream(std::ostream& stream)
{
uint64 bufferLength = memory.size();
stream.write((char*)&version, sizeof(uint64));
stream.write((char*)&bufferLength, sizeof(uint64));
stream.write((char*)memory.data(), memory.size());
}
void ArchiveBuffer::readFromStream(std::istream& stream)
{
stream.read((char*)&version, sizeof(uint64));
uint64 bufferLength = 0;
stream.read((char*)&bufferLength, sizeof(uint64));
memory.resize(bufferLength);
stream.read((char*)memory.data(), bufferLength);
}
bool ArchiveBuffer::eof() const
{
return position == memory.size();
}
void ArchiveBuffer::rewind()
{
position = 0;
}
Gfx::PGraphics& ArchiveBuffer::getGraphics()
{
return graphics;
}
+135 -2
View File
@@ -1,13 +1,146 @@
#pragma once
#include "Array.h"
#include "MinimalEngine.h"
#include "Containers/Array.h"
#include "Concepts.h"
#include <string>
namespace Seele
{
DECLARE_NAME_REF(Gfx, Graphics)
class ArchiveBuffer
{
public:
ArchiveBuffer();
ArchiveBuffer(Gfx::PGraphics graphics);
void writeBytes(const void* data, uint64 size);
void readBytes(void* dest, uint64 size);
void writeToStream(std::ostream& stream);
void readFromStream(std::istream& stream);
bool eof() const;
void rewind();
Gfx::PGraphics& getGraphics();
private:
Gfx::PGraphics graphics;
uint64 version = 0;
uint64 position = 0;
Array<uint8> memory;
};
namespace Serialization
{
template<std::integral T>
static void save(ArchiveBuffer& buffer, const T& type)
{
buffer.writeBytes(&type, sizeof(type));
}
template<std::integral T>
static void load(ArchiveBuffer& buffer, T& type)
{
buffer.readBytes(&type, sizeof(type));
}
template<std::floating_point T>
static void save(ArchiveBuffer& buffer, const T& type)
{
buffer.writeBytes(&type, sizeof(type));
}
template<std::floating_point T>
static void load(ArchiveBuffer& buffer, T& type)
{
buffer.readBytes(&type, sizeof(type));
}
template<enumeration T>
static void save(ArchiveBuffer& buffer, const T& type)
{
buffer.writeBytes(&type, sizeof(type));
}
template<enumeration T>
static void load(ArchiveBuffer& buffer, T& type)
{
buffer.readBytes(&type, sizeof(type));
}
//template<class T>
//static void save(ArchiveBuffer& buffer, const T& type)
//{
// type->save(buffer);
//}
//template<class T>
//static void load(ArchiveBuffer& buffer, T& type)
//{
// type->load(buffer);
//}
static void save(ArchiveBuffer& buffer, const std::string& type)
{
uint64 length = type.size();
buffer.writeBytes(&length, sizeof(uint64));
buffer.writeBytes(type.data(), type.size() * sizeof(char));
}
static void load(ArchiveBuffer& buffer, std::string& type)
{
uint64 length = 0;
buffer.readBytes(&length, sizeof(uint64));
type.resize(length);
buffer.readBytes(type.data(), length * sizeof(char));
}
//template<typename T>
//static void save(ArchiveBuffer& buffer, const RefPtr<T>& ptr)
//{
// Serialization::save(buffer, *ptr.getHandle());
//}
//template<typename T>
//static void load(ArchiveBuffer& buffer, RefPtr<T>& ptr)
//{
// Serialization::load(buffer, *ptr.getHandle());
//}
template<std::integral T>
static void save(ArchiveBuffer& buffer, const Array<T>& type)
{
uint64 length = type.size();
buffer.writeBytes(&length, sizeof(uint64));
buffer.writeBytes(type.data(), sizeof(T) * type.size());
}
template<std::integral T>
static void load(ArchiveBuffer& buffer, Array<T>& type)
{
uint64 length = 0;
buffer.readBytes(&length, sizeof(uint64));
type.resize(length);
buffer.readBytes(type.data(), sizeof(T) * type.size());
}
template<std::floating_point T>
static void save(ArchiveBuffer& buffer, const Array<T>& type)
{
uint64 length = type.size();
buffer.writeBytes(&length, sizeof(uint64));
buffer.writeBytes(type.data(), sizeof(T) * type.size());
}
template<std::floating_point T>
static void load(ArchiveBuffer& buffer, Array<T>& type)
{
uint64 length = 0;
buffer.readBytes(&length, sizeof(uint64));
type.resize(length);
buffer.readBytes(type.data(), sizeof(T) * type.size());
}
template<typename T>
static void save(ArchiveBuffer& buffer, const Array<T>& type) requires (!std::is_integral_v<T> && !std::is_floating_point_v<T>)
{
uint64 length = type.size();
buffer.writeBytes(&length, sizeof(uint64));
for (const auto& x : type)
{
save(buffer, x);
}
}
template<typename T>
static void load(ArchiveBuffer& buffer, Array<T>& type)
{
uint64 length = 0;
buffer.readBytes(&length, sizeof(uint64));
type.resize(length);
for (auto& x : type)
{
load(buffer, x);
}
}
} // namespace Serialization
} // namespace Seele
+2 -1
View File
@@ -1,6 +1,7 @@
target_sources(Engine
PRIVATE
ArchiveBuffer.h)
ArchiveBuffer.h
ArchiveBuffer.cpp)
target_sources(Engine
+2
View File
@@ -1,5 +1,7 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/Array.h"
#include "Math/Math.h"
namespace Seele
{
+1
View File
@@ -9,3 +9,4 @@ target_include_directories(Seele_unit_tests PUBLIC ./)
add_subdirectory(Containers/)
add_subdirectory(Graphics/)
add_subdirectory(Math/)
add_subdirectory(Serialization/)
@@ -0,0 +1,10 @@
#include "EngineTest.h"
#include <boost/test/unit_test.hpp>
using namespace Seele;
BOOST_AUTO_TEST_SUITE(SaveLoadKtx)
BOOST_AUTO_TEST_CASE(empty_constructur)
{
}
+3
View File
@@ -0,0 +1,3 @@
target_sources(Seele_unit_tests
PRIVATE
ArchiveBuffer.cpp)