implemented basic shader expressions

This commit is contained in:
Dynamitos
2023-02-24 22:09:07 +01:00
parent 48fa098546
commit f46262b66e
67 changed files with 1390 additions and 852 deletions
+64
View File
@@ -0,0 +1,64 @@
#include "AssetImporter.h"
#include "FontLoader.h"
#include "TextureLoader.h"
#include "MaterialLoader.h"
#include "MeshLoader.h"
#include "Graphics/Graphics.h"
using namespace Seele;
void AssetImporter::importMesh(MeshImportArgs args)
{
if (get().registry->getOrCreateFolder(args.importPath)->meshes.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().meshLoader->importAsset(args);
}
void AssetImporter::importTexture(TextureImportArgs args)
{
if (get().registry->getOrCreateFolder(args.importPath)->textures.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().textureLoader->importAsset(args);
}
void AssetImporter::importFont(FontImportArgs args)
{
if (get().registry->getOrCreateFolder(args.importPath)->fonts.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().fontLoader->importAsset(args);
}
void AssetImporter::importMaterial(MaterialImportArgs args)
{
if (get().registry->getOrCreateFolder(args.importPath)->materials.contains(args.filePath.stem().string()))
{
// skip importing duplicates
return;
}
get().materialLoader->importAsset(args);
}
void AssetImporter::init(Gfx::PGraphics graphics, AssetRegistry* registry)
{
get().registry = registry;
get().meshLoader = new MeshLoader(graphics);
get().textureLoader = new TextureLoader(graphics);
get().materialLoader = new MaterialLoader(graphics);
get().fontLoader = new FontLoader(graphics);
}
AssetImporter& AssetImporter::get()
{
static AssetImporter instance;
return instance;
}
+27
View File
@@ -0,0 +1,27 @@
#pragma once
#include "MinimalEngine.h"
#include "Asset/AssetRegistry.h"
namespace Seele
{
DECLARE_REF(TextureLoader)
DECLARE_REF(FontLoader)
DECLARE_REF(MeshLoader)
DECLARE_REF(MaterialLoader)
class AssetImporter
{
public:
static void importMesh(struct MeshImportArgs args);
static void importTexture(struct TextureImportArgs args);
static void importFont(struct FontImportArgs args);
static void importMaterial(struct MaterialImportArgs args);
static void init(Gfx::PGraphics graphics, AssetRegistry* registry);
private:
static AssetImporter& get();
UPTextureLoader textureLoader;
UPFontLoader fontLoader;
UPMeshLoader meshLoader;
UPMaterialLoader materialLoader;
AssetRegistry* registry;
};
} // namespace Seele
+12
View File
@@ -0,0 +1,12 @@
target_sources(Editor
PRIVATE
AssetImporter.h
AssetImporter.cpp
FontLoader.h
FontLoader.cpp
MaterialLoader.h
MaterialLoader.cpp
MeshLoader.h
MeshLoader.cpp
TextureLoader.h
TextureLoader.cpp)
+76
View File
@@ -0,0 +1,76 @@
#include "FontLoader.h"
#include "Graphics/Graphics.h"
#include "Asset/FontAsset.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/GraphicsResources.h"
#include <ft2build.h>
#include FT_FREETYPE_H
using namespace Seele;
FontLoader::FontLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
}
FontLoader::~FontLoader()
{
}
void FontLoader::importAsset(FontImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PFontAsset asset = new FontAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerFont(asset);
import(args, asset);
}
// in case of the space character there is no bitmap
// so we create a single pixel empty texture
uint8 transparentPixel = 0;
void FontLoader::import(FontImportArgs args, PFontAsset asset)
{
FT_Library ft;
FT_Error error = FT_Init_FreeType(&ft);
assert(!error);
FT_Face 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)
{
if(FT_Load_Char(face, c, FT_LOAD_RENDER))
{
std::cout << "error loading " << (char)c << std::endl;
continue;
}
FontAsset::Glyph& glyph = asset->glyphs[c];
glyph.size = IVector2(face->glyph->bitmap.width, face->glyph->bitmap.rows);
glyph.bearing = IVector2(face->glyph->bitmap_left, face->glyph->bitmap_top);
glyph.advance = face->glyph->advance.x;
TextureCreateInfo imageData;
imageData.format = Gfx::SE_FORMAT_R8_UINT;
imageData.width = face->glyph->bitmap.width;
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.height == 0)
{
glyph.size.x = 1;
glyph.size.y = 1;
glyph.bearing.x = 0;
glyph.bearing.y = 0;
imageData.width = 1;
imageData.height = 1;
imageData.resourceData.size = sizeof(uint8);
imageData.resourceData.data = &transparentPixel;
}
glyph.texture = graphics->createTexture2D(imageData);
}
FT_Done_Face(face);
FT_Done_FreeType(ft);
asset->setStatus(Asset::Status::Ready);
}
+26
View File
@@ -0,0 +1,26 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <filesystem>
namespace Seele
{
DECLARE_REF(FontAsset)
DECLARE_NAME_REF(Gfx, Graphics)
struct FontImportArgs
{
std::filesystem::path filePath;
std::string importPath;
};
class FontLoader
{
public:
FontLoader(Gfx::PGraphics graphic);
~FontLoader();
void importAsset(FontImportArgs args);
private:
void import(FontImportArgs args, PFontAsset asset);
Gfx::PGraphics graphics;
};
DEFINE_REF(FontLoader)
} // namespace Seele
+233
View File
@@ -0,0 +1,233 @@
#include "MaterialLoader.h"
#include "Graphics/Graphics.h"
#include "Asset/MaterialAsset.h"
#include "Asset/AssetRegistry.h"
#include "Material/Material.h"
#include "Window/WindowManager.h"
#include "Material/ShaderExpression.h"
#include "Asset/TextureAsset.h"
#include <nlohmann/json.hpp>
using namespace Seele;
using json = nlohmann::json;
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
PMaterialAsset placeholderAsset = new MaterialAsset();
import(MaterialImportArgs{
.filePath = std::filesystem::absolute("./shaders/Placeholder.asset"),
.importPath = "",
}, placeholderAsset);
AssetRegistry::get().assetRoot->materials[""] = placeholderAsset;
}
MaterialLoader::~MaterialLoader()
{
}
void MaterialLoader::importAsset(MaterialImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PMaterialAsset asset = new MaterialAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerMaterial(asset);
import(args, asset);
}
void MaterialLoader::import(MaterialImportArgs args, PMaterialAsset asset)
{
auto stream = std::ifstream(args.filePath.c_str());
json j;
stream >> j;
std::string materialName = j["name"].get<std::string>() + "Material";
Gfx::PDescriptorLayout layout = graphics->createDescriptorLayout(materialName + "Layout");
//Shader file needs to conform to the slang standard, which prohibits _
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
materialName.erase(std::remove(materialName.begin(), materialName.end(), '.'), materialName.end());
uint32 uniformBufferOffset = 0;
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
uint32 uniformBinding = -1;
Map<int32, PShaderExpression> expressions;
int32 key = 0;
int32 auxKey = -1;
Map<std::string, PShaderParameter> parameters;
for(auto param : j["params"].items())
{
std::string type = param.value()["type"].get<std::string>();
auto defaultValue = param.value().find("default");
// TODO: ALIGNMENT RULES
if(type.compare("float") == 0)
{
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
p->key = auxKey;
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 4;
if(defaultValue != param.value().end())
{
p->data = std::stof(defaultValue.value().get<std::string>());
}
expressions[auxKey--] = p;
parameters[param.key()] = p;
}
// TODO: ALIGNMENT RULES
else if(type.compare("float3") == 0)
{
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
p->key = auxKey;
if(uniformBinding == -1)
{
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
uniformBinding = bindingCounter++;
}
uniformBufferOffset += 12;
if(defaultValue != param.value().end())
{
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
}
expressions[auxKey--] = p;
parameters[param.key()] = p;
}
else if(type.compare("Texture2D") == 0)
{
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
p->key = auxKey;
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
if(defaultValue != param.value().end())
{
std::string defaultString = defaultValue.value().get<std::string>();
p->data = AssetRegistry::findTexture(defaultString);
}
if(p->data == nullptr)
{
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
}
expressions[auxKey--] = p;
parameters[param.key()] = p;
}
else if(type.compare("SamplerState") == 0)
{
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
p->key = auxKey;
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
p->data = graphics->createSamplerState({});
expressions[auxKey--] = p;
parameters[param.key()] = p;
}
else
{
std::cout << "Error unsupported parameter type" << std::endl;
}
}
uint32 uniformDataSize = uniformBufferOffset;
auto referenceExpression = [&auxKey, &expressions](json obj) -> PShaderExpression
{
if(obj.is_string())
{
PConstantExpression c = new ConstantExpression(obj.get<std::string>(), ExpressionType::UNKNOWN);
c->key = auxKey;
expressions[auxKey--] = c;
return c;
}
else
{
return expressions[obj.get<uint32>()];
}
};
MaterialNode mat;
for(auto param : j["code"].items())
{
auto obj = param.value();
std::string exp = obj["exp"].get<std::string>();
if(exp.compare("Add") == 0)
{
PAddExpression p = new AddExpression();
p->key = key;
p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key;
p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key;
expressions[key++] = p;
}
if(exp.compare("Sub") == 0)
{
PSubExpression p = new SubExpression();
p->key = key;
p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key;
p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key;
expressions[key++] = p;
}
if(exp.compare("Mul") == 0)
{
PMulExpression p = new MulExpression();
p->key = key;
p->inputs["lhs"].source = referenceExpression(obj["lhs"])->key;
p->inputs["rhs"].source = referenceExpression(obj["rhs"])->key;
expressions[key++] = p;
}
if(exp.compare("Swizzle") == 0)
{
PSwizzleExpression p = new SwizzleExpression();
p->key = key;
p->inputs["target"].source = referenceExpression(obj["target"])->key;
int32 i = 0;
for(auto c : obj["comp"].items())
{
p->comp[i++] = c.value().get<uint32>();
}
expressions[key++] = p;
}
if(exp.compare("Sample") == 0)
{
PSampleExpression p = new SampleExpression();
p->key = key;
p->inputs["texture"].source = parameters[obj["texture"].get<std::string>()]->key;
p->inputs["sampler"].source = parameters[obj["sampler"].get<std::string>()]->key;
p->inputs["coords"].source = referenceExpression(obj["coords"])->key;
expressions[key++] = p;
}
if(exp.compare("BRDF") == 0)
{
mat.profile = obj["profile"].get<std::string>();
for(auto val : obj["values"].items())
{
mat.variables[val.key()] = referenceExpression(val.value());
}
}
}
layout->create();
Array<PShaderExpression> codeExp;
for(const auto& [_, e] : expressions)
{
codeExp.add(e);
}
Array<PShaderParameter> params;
for(const auto& [_, p] : parameters)
{
params.add(p);
}
asset->material = new Material(
graphics,
std::move(params),
std::move(layout),
uniformDataSize,
uniformBinding,
materialName,
std::move(codeExp),
std::move(mat)
);
asset->material->compile();
graphics->getShaderCompiler()->registerMaterial(asset->material);
asset->setStatus(Asset::Status::Ready);
////co_return;
}
PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
{
return placeholderMaterial;
}
+28
View File
@@ -0,0 +1,28 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <filesystem>
namespace Seele
{
DECLARE_REF(MaterialAsset)
DECLARE_NAME_REF(Gfx, Graphics)
struct MaterialImportArgs
{
std::filesystem::path filePath;
std::string importPath;
};
class MaterialLoader
{
public:
MaterialLoader(Gfx::PGraphics graphic);
~MaterialLoader();
void importAsset(MaterialImportArgs args);
PMaterialAsset getPlaceHolderMaterial();
private:
void import(MaterialImportArgs args, PMaterialAsset asset);
Gfx::PGraphics graphics;
PMaterialAsset placeholderMaterial;
};
DEFINE_REF(MaterialLoader)
} // namespace Seele
+328
View File
@@ -0,0 +1,328 @@
#include "MeshLoader.h"
#include "Graphics/GraphicsResources.h"
#include "Graphics/Graphics.h"
#include "Asset/MeshAsset.h"
#include "Graphics/Mesh.h"
#include "Graphics/StaticMeshVertexInput.h"
#include "Asset/AssetImporter.h"
#include "Asset/MaterialAsset.h"
#include <fstream>
#include <iostream>
#include <nlohmann/json.hpp>
#include <stb_image_write.h>
#include <assimp/config.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/material.h>
#include <Asset/MaterialLoader.h>
#include <Asset/TextureLoader.h>
using namespace Seele;
MeshLoader::MeshLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
}
MeshLoader::~MeshLoader()
{
}
void MeshLoader::importAsset(MeshImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PMeshAsset asset = new MeshAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
AssetRegistry::get().registerMesh(asset);
import(args, asset);
}
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"] = baseName + material->GetName().C_Str();
matCode["profile"] = "BlinnPhong"; //TODO: other shading models
aiString texPath;
//TODO make samplers based on used textures
matCode["params"]["textureSampler"] =
{
{"type", "SamplerState"}
};
if(material->GetTexture(aiTextureType_DIFFUSE, 0, &texPath) == AI_SUCCESS)
{
std::string texFilename = std::filesystem::path(texPath.C_Str()).replace_extension("asset").stem().string();
matCode["params"]["diffuseTexture"] =
{
{"type", "Texture2D"},
{"default", texFilename}
};
matCode["code"].push_back(
{
{ "exp", "Sample" },
{ "texture", "diffuseTexture" },
{ "sampler", "textureSampler" },
{ "coords", "input.texCoords[0]"}
}
);
matCode["code"].push_back(
{
{ "exp", "Swizzle" },
{ "target", 0 },
{ "comp", json::array({0, 1, 2}) },
}
);
matCode["code"].push_back(
{
{ "exp", "BRDF" },
{ "profile", "BlinnPhong" },
{ "values", {
{"baseColor", 1}
}}
}
);
}
else
{
matCode["code"].push_back(
{
{ "exp", "BRDF" },
{ "profile", "BlinnPhong" },
{ "values", {
{"baseColor", "input.vertexColor.xyz"}
}}
}
);
}
if(material->GetTexture(aiTextureType_SPECULAR, 0, &texPath) == AI_SUCCESS)
{
}
if(material->GetTexture(aiTextureType_NORMALS, 0, &texPath) == AI_SUCCESS)
{
}
std::string outMatFilename = matCode["name"].get<std::string>().append(".asset");
std::ofstream outMatFile = std::ofstream(meshDirectory / outMatFilename);
outMatFile << std::setw(4) << matCode;
outMatFile.flush();
outMatFile.close();
std::cout << "writing json to " << outMatFilename << std::endl;
AssetImporter::importMaterial(MaterialImportArgs{
.filePath = meshDirectory / outMatFilename,
.importPath = importPath,
});
globalMaterials[i] = AssetRegistry::findMaterial(matCode["name"].get<std::string>());
}
}
void findMeshRoots(aiNode *node, List<aiNode *> &meshNodes)
{
if (node->mNumMeshes > 0)
{
meshNodes.add(node);
return;
}
for (uint32 i = 0; i < node->mNumChildren; ++i)
{
findMeshRoots(node->mChildren[i], meshNodes);
}
}
VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics)
{
Array<Vector> buffer(size);
for(uint32 i = 0; i < size; ++i)
{
buffer[i] = Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z);
}
VertexBufferCreateInfo vbInfo;
vbInfo.numVertices = size;
vbInfo.vertexSize = sizeof(Vector);
vbInfo.resourceData.data = (uint8 *)buffer.data();
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
vbInfo.resourceData.size = sizeof(Vector) * buffer.size();
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
}
VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
{
Array<Vector2> buffer(size);
for(uint32 i = 0; i < size; ++i)
{
buffer[i] = Vector2(sourceData[i].x, sourceData[i].y);
}
VertexBufferCreateInfo vbInfo;
vbInfo.numVertices = size;
vbInfo.vertexSize = sizeof(Vector2);
vbInfo.resourceData.data = (uint8 *)buffer.data();
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
vbInfo.resourceData.size = sizeof(Vector2) * buffer.size();
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
}
VertexStreamComponent createVertexStream(uint32 size, aiColor4D* sourceData, Gfx::PGraphics graphics)
{
Array<Vector4> buffer(size);
for(uint32 i = 0; i < size; ++i)
{
buffer[i] = Vector4(sourceData[i].r, sourceData[i].g, sourceData[i].b, sourceData[i].a);
}
VertexBufferCreateInfo vbInfo;
vbInfo.numVertices = size;
vbInfo.vertexSize = sizeof(Vector4);
vbInfo.resourceData.data = (uint8 *)buffer.data();
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
vbInfo.resourceData.size = sizeof(Vector4) * buffer.size();
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
vertexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT);
}
void MeshLoader::loadGlobalMeshes(const aiScene* scene, const Array<PMaterialAsset>& materials, Array<PMesh>& globalMeshes, Component::Collider& collider)
{
for (uint32 meshIndex = 0; meshIndex < scene->mNumMeshes; ++meshIndex)
{
aiMesh *mesh = scene->mMeshes[meshIndex];
collider.boundingbox.adjust(Vector(mesh->mAABB.mMin.x, mesh->mAABB.mMin.y, mesh->mAABB.mMin.z));
collider.boundingbox.adjust(Vector(mesh->mAABB.mMax.x, mesh->mAABB.mMax.y, mesh->mAABB.mMax.z));
//! \todo duplicate from createVertexStream, clean up
Array<Vector> vertices(mesh->mNumVertices);
for(uint32 i = 0; i < mesh->mNumVertices; ++i)
{
vertices[i] = Vector(mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z);
}
PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
StaticMeshDataType data;
data.positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
for(uint32 i = 0; i < MAX_TEXCOORDS; ++i)
{
if(mesh->HasTextureCoords(i))
{
data.textureCoordinates[i] = createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics);
}
}
if(mesh->HasNormals())
{
data.tangentBasisComponents[0] = createVertexStream(mesh->mNumVertices, mesh->mNormals, graphics);
}
if(mesh->HasTangentsAndBitangents())
{
//TODO: use bitangent to calculate sign for 4th coordinate of tangentstream
data.tangentBasisComponents[1] = createVertexStream(mesh->mNumVertices, mesh->mTangents, graphics);
data.tangentBasisComponents[2] = createVertexStream(mesh->mNumVertices, mesh->mBitangents, graphics);
}
if(mesh->HasVertexColors(0))
{
data.colorComponent = createVertexStream(mesh->mNumVertices, mesh->mColors[0], graphics);
}
vertexShaderInput->setData(std::move(data));
vertexShaderInput->init(graphics);
Array<uint32> indices(mesh->mNumFaces * 3);
for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex)
{
indices[faceIndex * 3 + 0] = mesh->mFaces[faceIndex].mIndices[0];
indices[faceIndex * 3 + 1] = mesh->mFaces[faceIndex].mIndices[1];
indices[faceIndex * 3 + 2] = mesh->mFaces[faceIndex].mIndices[2];
}
collider.physicsMesh.addCollider(vertices, indices, Matrix4(1.0f));
IndexBufferCreateInfo idxInfo;
idxInfo.indexType = Gfx::SE_INDEX_TYPE_UINT32;
idxInfo.resourceData.data = (uint8 *)indices.data();
idxInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
idxInfo.resourceData.size = sizeof(uint32) * indices.size();
Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
globalMeshes[meshIndex] = new Mesh(vertexShaderInput, indexBuffer);
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
}
}
void MeshLoader::convertAssimpARGB(unsigned char* dst, aiTexel* src, uint32 numPixels)
{
for(uint32 i = 0; i < numPixels; ++i)
{
dst[i * 4 + 0] = src[i].r;
dst[i * 4 + 1] = src[i].g;
dst[i * 4 + 2] = src[i].b;
dst[i * 4 + 3] = src[i].a;
}
}
void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& meshDirectory, const std::string& importPath)
{
for (uint32 i = 0; i < scene->mNumTextures; ++i)
{
aiTexture* tex = scene->mTextures[i];
auto texPath = std::filesystem::path(tex->mFilename.C_Str());
auto texPngPath = meshDirectory;
texPngPath.append(texPath.filename().string());
if(tex->mHeight == 0)
{
// already compressed, just dump it to the disk
std::ofstream file(texPngPath, std::ios::binary);
file.write((const char*)tex->pcData, tex->mWidth);
file.flush();
}
else
{
// recompress data so that the TextureLoader can read it
unsigned char* texData = new unsigned char[tex->mWidth * tex->mHeight * 4];
convertAssimpARGB(texData, tex->pcData, tex->mWidth * tex->mHeight);
stbi_write_png(texPngPath.string().c_str(), tex->mWidth, tex->mHeight, 4, tex->pcData, tex->mWidth * 32);
delete[] texData;
}
std::cout << "Loading model texture " << texPngPath.string() << std::endl;
AssetImporter::importTexture(TextureImportArgs {
.filePath = texPath,
.importPath = importPath,
});
}
}
void MeshLoader::import(MeshImportArgs args, PMeshAsset meshAsset)
{
std::cout << "Starting to import "<<args.filePath<< std::endl;
meshAsset->setStatus(Asset::Status::Loading);
Assimp::Importer importer;
importer.ReadFile(args.filePath.string().c_str(), (uint32)(
aiProcess_FlipUVs |
aiProcess_Triangulate |
aiProcess_SortByPType |
aiProcess_GenBoundingBoxes |
aiProcess_GenSmoothNormals |
aiProcess_GenUVCoords |
aiProcess_FindDegenerates));
const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
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;
loadGlobalMeshes(scene, globalMaterials, globalMeshes, collider);
List<aiNode *> meshNodes;
findMeshRoots(scene->mRootNode, meshNodes);
for (auto meshNode : meshNodes)
{
for(uint32 i = 0; i < meshNode->mNumMeshes; ++i)
{
meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]);
}
}
meshAsset->physicsMesh = std::move(collider);
meshAsset->setStatus(Asset::Status::Ready);
std::cout << "Finished loading " << args.filePath<< std::endl;
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include "Component/Collider.h"
#include <filesystem>
struct aiScene;
struct aiTexel;
namespace Seele
{
DECLARE_REF(Mesh)
DECLARE_REF(MeshAsset)
DECLARE_REF(MaterialAsset)
DECLARE_NAME_REF(Gfx, Graphics)
struct MeshImportArgs
{
std::filesystem::path filePath;
std::string importPath;
};
class MeshLoader
{
public:
MeshLoader(Gfx::PGraphics graphic);
~MeshLoader();
void importAsset(MeshImportArgs args);
private:
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);
Gfx::PGraphics graphics;
};
DEFINE_REF(MeshLoader)
} // namespace Seele
+136
View File
@@ -0,0 +1,136 @@
#include "TextureLoader.h"
#include "Asset/TextureAsset.h"
#include "Graphics/Graphics.h"
#include "Asset/AssetRegistry.h"
#include "Graphics/Vulkan/VulkanGraphicsEnums.h"
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include <stb_image_write.h>
#include "ktx.h"
using namespace Seele;
TextureLoader::TextureLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{
//(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()
{
}
void TextureLoader::importAsset(TextureImportArgs args)
{
std::filesystem::path assetPath = args.filePath.filename();
assetPath.replace_extension("asset");
PTextureAsset asset = new TextureAsset(args.importPath, assetPath.stem().string());
asset->setStatus(Asset::Status::Loading);
asset->setTexture(placeholderAsset->getTexture());
AssetRegistry::get().registerTexture(asset);
import(args, asset);
}
PTextureAsset TextureLoader::getPlaceholderTexture()
{
return placeholderAsset;
}
void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset)
{
int totalWidth, totalHeight, n;
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.baseWidth = totalWidth / 4;
createInfo.baseHeight = totalHeight / 3;
createInfo.numFaces = 6;
createInfo.numDimensions = 2;
ktxTexture2_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
&kTexture);
auto loadCubeFace = [&kTexture, &faceWidth, &totalWidth, &data](int xPos, int yPos, int faceName)
{
std::vector<unsigned char> vec(faceWidth * faceWidth * 4);
for (int y = 0; y < faceWidth; ++y)
{
for (int x = 0; x < faceWidth; ++x)
{
int imgX = x + (xPos * faceWidth);
int imgY = y + (yPos * faceWidth);
std::memcpy(&vec[(x + (faceWidth * y)) * 4], &data[(imgX + (totalWidth * imgY)) * 4], 4);
}
}
ktxTexture_SetImageFromMemory(ktxTexture(kTexture),
0, 0, faceName, vec.data(), vec.size());
};
loadCubeFace(2, 1, 0); // +X
loadCubeFace(0, 1, 1); // -X
loadCubeFace(1, 0, 2); // +Y
loadCubeFace(1, 2, 3); // -Y
loadCubeFace(1, 1, 4); // +Z
loadCubeFace(3, 1, 5); // -Z
}
else
{
createInfo.baseWidth = totalWidth;
createInfo.baseHeight = totalHeight;
createInfo.numFaces = 1;
createInfo.numDimensions = 1 + (totalHeight > 1);
ktxTexture2_Create(&createInfo,
KTX_TEXTURE_CREATE_ALLOC_STORAGE,
&kTexture);
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);
ktx_uint8_t* dest;
ktx_size_t size;
ktxTexture_WriteToMemory(ktxTexture(kTexture), &dest, &size);
Array<uint8> memory(size);
std::memcpy(memory.data(), dest, size);
textureAsset->createFromMemory(std::move(memory), graphics);
free(dest);
stbi_image_free(data);
////co_return;
}
+37
View File
@@ -0,0 +1,37 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include "Graphics/GraphicsEnums.h"
#include <filesystem>
namespace Seele
{
DECLARE_REF(TextureAsset)
DECLARE_NAME_REF(Gfx, Graphics)
DECLARE_NAME_REF(Gfx, Texture2D)
enum class TextureImportType
{
TEXTURE_2D,
TEXTURE_CUBEMAP,
};
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
{
public:
TextureLoader(Gfx::PGraphics graphic);
~TextureLoader();
void importAsset(TextureImportArgs args);
PTextureAsset getPlaceholderTexture();
private:
void import(TextureImportArgs args, PTextureAsset asset);
Gfx::PGraphics graphics;
PTextureAsset placeholderAsset;
};
DEFINE_REF(TextureLoader)
} // namespace Seele
+1 -1
View File
@@ -1,4 +1,4 @@
add_subdirectory(Platform/)
add_subdirectory(Asset/)
add_subdirectory(Window/)
target_sources(Editor
-1
View File
@@ -1 +0,0 @@
add_subdirectory(Windows/)
@@ -1,4 +0,0 @@
target_sources(Editor
PRIVATE
GameInterface.h
GameInterface.cpp)
@@ -1,31 +0,0 @@
#include "GameInterface.h"
using namespace Seele;
GameInterface::GameInterface(std::string dllPath)
: dllPath(dllPath)
{
}
GameInterface::~GameInterface()
{
}
Game* GameInterface::getGame()
{
return game;
}
void GameInterface::reload(AssetRegistry* registry)
{
if(lib != NULL)
{
destroyInstance(game);
FreeLibrary(lib);
}
lib = LoadLibraryA(dllPath.c_str());
createInstance = (decltype(createInstance))GetProcAddress(lib, "createInstance");
destroyInstance = (decltype(destroyInstance))GetProcAddress(lib, "destroyInstance");
game = createInstance(registry);
}
@@ -1,21 +0,0 @@
#pragma once
#include "Game.h"
#include "Windows.h"
namespace Seele
{
class GameInterface
{
public:
GameInterface(std::string dllPath);
~GameInterface();
Game* getGame();
void reload(AssetRegistry* registry);
private:
HMODULE lib = NULL;
std::string dllPath;
Game* game;
Game* (*createInstance)(AssetRegistry*) = nullptr;
void (*destroyInstance)(Game*) = nullptr;
};
} // namespace Seele
+2 -2
View File
@@ -1,9 +1,9 @@
target_sources(Editor
PRIVATE
GameView.h
GameView.cpp
InspectorView.h
InspectorView.cpp
PlayView.h
PlayView.cpp
SceneView.h
SceneView.cpp
ViewportControl.h
-324
View File
@@ -1,324 +0,0 @@
#include "GameView.h"
#include "Graphics/Graphics.h"
#include "Window/Window.h"
#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;
AssetRegistry* instance = new AssetRegistry();
GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo)
: View(graphics, window, createInfo, "Game")
, gameInterface("C:\\Users\\Dynamitos\\TrackClear\\bin\\TrackCleard.dll")
, renderGraph(RenderGraphBuilder::build(
DepthPrepass(graphics),
LightCullingPass(graphics),
BasePass(graphics),
#ifdef EDITOR
DebugPass(graphics),
#endif
SkyboxRenderPass(graphics)
))
{
scene = new Scene(graphics);
gameInterface.reload(instance);
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);
}
GameView::~GameView()
{
}
void GameView::beginUpdate()
{
}
void GameView::update()
{
static auto startTime = std::chrono::high_resolution_clock::now();
systemGraph->run(threadPool, updateTime);
scene->update(updateTime);
auto endTime = std::chrono::high_resolution_clock::now();
std::chrono::duration<float> duration = (endTime - startTime);
updateTime = duration.count();
startTime = endTime;
}
void GameView::commitUpdate()
{
depthPrepassData.staticDrawList = scene->getStaticMeshes();
depthPrepassData.sceneDataBuffer = scene->getSceneDataBuffer();
lightCullingData.lightEnv = scene->getLightBuffer();
basePassData.staticDrawList = scene->getStaticMeshes();
basePassData.sceneDataBuffer = scene->getSceneDataBuffer();
skyboxData.skybox = scene->getSkybox();
#ifdef EDITOR
if(showDebug)
{
debugPassData.vertices = Seele::gDebugVertices;
}
#endif
Seele::gDebugVertices.clear();
}
void GameView::prepareRender()
{
#ifdef EDITOR
renderGraph.updatePassData(depthPrepassData, lightCullingData, basePassData, debugPassData, skyboxData);
#else
renderGraph.updatePassData(depthPrepassData, lightCullingData, basePassData, skyboxData);
#endif
}
void GameView::render()
{
scene->view<Component::Camera>([&](Component::Camera& cam)
{
if(cam.mainCamera)
{
renderGraph.render(cam);
}
});
}
void GameView::keyCallback(KeyCode code, InputAction action, KeyModifier)
{
scene->view<Component::KeyboardInput>([=](Component::KeyboardInput& input)
{
//if(code == KeyCode::KEY_R && action == InputAction::PRESS)
//{
// auto cubeMesh = AssetRegistry::findMesh("cube");
// PEntity cube2 = new Entity(scene);
// Component::Transform& cube2Transform = cube2->attachComponent<Component::Transform>();
// cube2Transform.setPosition(Vector(0, 20, 0));
// cube2Transform.setRotation(Quaternion(Vector(0.f, 90.f, 90.f)));
// cube2Transform.setScale(Vector(2.f, 2.f, 2.f));
// cubeMesh->physicsMesh.type = Component::ColliderType::DYNAMIC;
// cube2->attachComponent<Component::Collider>(cubeMesh->physicsMesh);
// cube2->attachComponent<Component::StaticMesh>(cubeMesh);
// Component::RigidBody& physics2 = cube2->attachComponent<Component::RigidBody>();
// physics2.linearMomentum = Vector(0, -10, 0);
// physics2.angularMomentum = Vector(0, 0, 0);
//}
//
//if(code == KeyCode::KEY_B && action == InputAction::PRESS)
//{
// showDebug = !showDebug;
// debugPassData.vertices.clear();
//}
input.keys[code] = action != InputAction::RELEASE;
});
}
void GameView::mouseMoveCallback(double xPos, double yPos)
{
scene->view<Component::KeyboardInput>([=](Component::KeyboardInput& input)
{
input.mouseX = static_cast<float>(xPos);
input.mouseY = static_cast<float>(yPos);
});
}
void GameView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier)
{
scene->view<Component::KeyboardInput>([=](Component::KeyboardInput& input)
{
if (button == MouseButton::MOUSE_BUTTON_1)
{
input.mouse1 = action != InputAction::RELEASE;
}
if (button == MouseButton::MOUSE_BUTTON_2)
{
input.mouse2 = action != InputAction::RELEASE;
}
});
}
void GameView::scrollCallback(double, double)
{
}
void GameView::fileCallback(int, const char**)
{
}
-59
View File
@@ -1,59 +0,0 @@
#pragma once
#include "Window/View.h"
#include "Scene/Scene.h"
#include "Graphics/RenderPass/DepthPrepass.h"
#include "Graphics/RenderPass/LightCullingPass.h"
#include "Graphics/RenderPass/BasePass.h"
#include "Graphics/RenderPass/DebugPass.h"
#include "Graphics/RenderPass/SkyboxRenderPass.h"
#include "Platform/Windows/GameInterface.h" // TODO
namespace Seele
{
class GameView : public View
{
public:
GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo);
virtual ~GameView();
virtual void beginUpdate() override;
virtual void update() override;
virtual void commitUpdate() override;
virtual void prepareRender() override;
virtual void render() override;
private:
GameInterface gameInterface;
RenderGraph<
DepthPrepass,
LightCullingPass,
BasePass,
#ifdef EDITOR
DebugPass,
#endif
SkyboxRenderPass
> renderGraph;
DepthPrepassData depthPrepassData;
LightCullingPassData lightCullingData;
BasePassData basePassData;
SkyboxPassData skyboxData;
#ifdef EDITOR
DebugPassData debugPassData;
#endif
PScene scene;
PSystemGraph systemGraph;
dp::thread_pool<> threadPool;
float updateTime = 0;
#ifdef EDITOR
bool showDebug = false;
#endif
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
virtual void mouseMoveCallback(double xPos, double yPos) override;
virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override;
virtual void scrollCallback(double xOffset, double yOffset) override;
virtual void fileCallback(int count, const char** paths) override;
};
DEFINE_REF(GameView)
} // namespace Seele
+3 -5
View File
@@ -1,24 +1,22 @@
#include "InspectorView.h"
#include "Graphics/Graphics.h"
#include "Actor/Actor.h"
#include "Window/Window.h"
#include "Asset/AssetRegistry.h"
#include "Asset/FontLoader.h"
#include "UI/System.h"
#include "Window/Window.h"
using namespace Seele;
using namespace Seele::Editor;
InspectorView::InspectorView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo &createInfo)
: View(graphics, window, createInfo, "InspectorView")
: View(graphics, std::move(window), std::move(createInfo), "InspectorView")
, renderGraph(RenderGraphBuilder::build(
UIPass(graphics),
TextPass(graphics)
))
, uiSystem(new UI::System())
{
AssetRegistry::importFont(FontImportArgs{
.filePath = "./fonts/Calibri.ttf",
});
renderGraph.updateViewport(viewport);
uiSystem->updateViewport(viewport);
}
+3
View File
@@ -8,6 +8,8 @@
namespace Seele
{
DECLARE_REF(Actor)
namespace Editor
{
class InspectorView : public View
{
public:
@@ -39,4 +41,5 @@ protected:
virtual void fileCallback(int count, const char** paths) override;
};
DEFINE_REF(InspectorView)
} // namespace Editor
} // namespace Seele
+39
View File
@@ -0,0 +1,39 @@
#include "PlayView.h"
#include "Window/Window.h"
using namespace Seele;
using namespace Seele::Editor;
PlayView::PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath)
: GameView(std::move(graphics), std::move(window), std::move(createInfo), dllPath)
{
}
PlayView::~PlayView()
{
}
void PlayView::beginUpdate()
{
GameView::beginUpdate();
}
void PlayView::update()
{
GameView::update();
}
void PlayView::commitUpdate()
{
GameView::commitUpdate();
}
void PlayView::prepareRender()
{
GameView::prepareRender();
}
void PlayView::render()
{
GameView::render();
}
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include "Window/GameView.h"
namespace Seele
{
namespace Editor
{
class PlayView : public GameView
{
public:
PlayView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath);
virtual ~PlayView();
virtual void beginUpdate() override;
virtual void update() override;
virtual void commitUpdate() override;
virtual void prepareRender() override;
virtual void render() override;
private:
};
DECLARE_REF(PlayView)
} // namespace Editor
} // namespace Seele
-1
View File
@@ -11,7 +11,6 @@ namespace Seele
DECLARE_REF(Scene)
namespace Editor
{
class SceneView : public View
{
public:
+1
View File
@@ -2,6 +2,7 @@
#include "Component/Camera.h"
using namespace Seele;
using namespace Seele::Editor;
ViewportControl::ViewportControl(const URect& viewportDimensions, Vector initialPos)
: position(initialPos)
+25 -22
View File
@@ -5,27 +5,30 @@
namespace Seele
{
class ViewportControl
namespace Editor
{
public:
ViewportControl(const URect& viewportDimensions, Vector initialPos /*TODO: configurable initial rotations*/);
~ViewportControl();
void update(Component::Camera& camera, float deltaTime);
void keyCallback(KeyCode key, InputAction action);
void mouseMoveCallback(double xPos, double yPos);
void mouseButtonCallback(MouseButton button, InputAction action);
void viewportResize(URect dimensions);
private:
Vector position;
Vector springArm;
float fieldOfView;
float aspectRatio;
StaticArray<bool, static_cast<size_t>(KeyCode::KEY_LAST)> keys;
bool mouse1 = false;
bool mouse2 = false;
float mouseX;
float mouseY;
float pitch;
float yaw;
};
class ViewportControl
{
public:
ViewportControl(const URect& viewportDimensions, Vector initialPos /*TODO: configurable initial rotations*/);
~ViewportControl();
void update(Component::Camera& camera, float deltaTime);
void keyCallback(KeyCode key, InputAction action);
void mouseMoveCallback(double xPos, double yPos);
void mouseButtonCallback(MouseButton button, InputAction action);
void viewportResize(URect dimensions);
private:
Vector position;
Vector springArm;
float fieldOfView;
float aspectRatio;
StaticArray<bool, static_cast<size_t>(KeyCode::KEY_LAST)> keys;
bool mouse1 = false;
bool mouse2 = false;
float mouseX;
float mouseY;
float pitch;
float yaw;
};
} // namespace Editor
} // namespace Seele
+184 -2
View File
@@ -1,14 +1,22 @@
#include "Window/WindowManager.h"
#include "Window/SceneView.h"
#include "Window/GameView.h"
#include "Window/PlayView.h"
#include "Window/InspectorView.h"
#include "Asset/AssetRegistry.h"
#include "Asset/AssetImporter.h"
#include "Asset/TextureLoader.h"
#include "Graphics/Vulkan/VulkanGraphics.h"
#include "Asset/MeshLoader.h"
#include "Asset/TextureLoader.h"
#include "Asset/MaterialLoader.h"
#include "Asset/FontLoader.h"
#include "Asset/AssetImporter.h"
using namespace Seele;
using namespace Seele::Editor;
extern AssetRegistry* instance;
int main()
{
Gfx::PGraphics graphics = new Vulkan::Graphics();
@@ -17,6 +25,180 @@ int main()
graphics->init(initializer);
PWindowManager windowManager = new WindowManager();
AssetRegistry::init(std::string("C:\\Users\\Dynamitos\\TrackClear\\Assets"), graphics);
AssetImporter::init(graphics, instance);
AssetImporter::importFont(FontImportArgs{
.filePath = "./fonts/Calibri.ttf",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/arena.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/train.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/bird.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/cube.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/flameThrower.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/player.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/shotgun.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/track.fbx",
});
AssetImporter::importMesh(MeshImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/models/zombie.fbx",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Dirt.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/DirtGrass.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Grass.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Ice.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Lava.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Obsidian.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Rocks.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Sand.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Water.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/Wood.png",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/blendMap.png",
.importPath = "level0",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/heightMap.png",
.importPath = "level0",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level0/trackMap.png",
.importPath = "level0",
});
AssetImporter::importMaterial(MaterialImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/shaders/TerrainMaterial.json",
.importPath = "level0",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/blendMap.png",
.importPath = "level1",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/heightMap.png",
.importPath = "level1",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level1/trackMap.png",
.importPath = "level1",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/blendMap.png",
.importPath = "level2",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/heightMap.png",
.importPath = "level2",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level2/trackMap.png",
.importPath = "level2",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/blendMap.png",
.importPath = "level3",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/heightMap.png",
.importPath = "level3",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level3/trackMap.png",
.importPath = "level3",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/blendMap.png",
.importPath = "level4",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/heightMap.png",
.importPath = "level4",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level4/trackMap.png",
.importPath = "level4",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/blendMap.png",
.importPath = "level5",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/heightMap.png",
.importPath = "level5",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level5/trackMap.png",
.importPath = "level5",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/blendMap.png",
.importPath = "level6",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/heightMap.png",
.importPath = "level6",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level6/trackMap.png",
.importPath = "level6",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/blendMap.png",
.importPath = "level7",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/heightMap.png",
.importPath = "level7",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/textures/level7/trackMap.png",
.importPath = "level7",
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/skyboxes/FS000_Day_01.png",
.type = TextureImportType::TEXTURE_CUBEMAP,
});
AssetImporter::importTexture(TextureImportArgs{
.filePath = "C:/Users/Dynamitos/TrackClear/old_resources/skyboxes/FS000_Night_01.png",
.type = TextureImportType::TEXTURE_CUBEMAP,
});
AssetRegistry::saveRegistry();
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
@@ -31,7 +213,7 @@ int main()
sceneViewInfo.dimensions.size.y = 720;
sceneViewInfo.dimensions.offset.x = 0;
sceneViewInfo.dimensions.offset.y = 0;
PGameView sceneView = new GameView(graphics, window, sceneViewInfo);
PGameView sceneView = new Editor::PlayView(graphics, window, sceneViewInfo, "C:\\Users\\Dynamitos\\TrackClear\\bin\\TrackCleard.dll");
//ViewportCreateInfo inspectorViewInfo;
//inspectorViewInfo.dimensions.size.x = 640;