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
+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();
return assetId;
}
std::string Asset::getFullPath() const
{
return fullPath.generic_string();
}
std::string Asset::getExtension() const
{
return extension.generic_string();
}
+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;
};
+265 -39
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)
{
AssetFolder& folder = getOrCreateFolder(importPath);
folder.fonts[font->getFileName()] = font;
void AssetRegistry::saveRegistryInternal()
{
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,66 +7,115 @@
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(std::string_view folderPath, std::string_view name)
: Asset(folderPath, name)
{
}
TextureAsset::TextureAsset(const std::filesystem::path& fullPath)
: Asset(fullPath)
{
}
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
{