Improving Material shader code generation

This commit is contained in:
Dynamitos
2020-09-19 14:36:50 +02:00
parent 6814587b54
commit facbfed79c
72 changed files with 1049 additions and 329 deletions
+13 -1
View File
@@ -4,6 +4,7 @@
"git.enabled": false, "git.enabled": false,
"files.associations": { "files.associations": {
"*.h": "cpp", "*.h": "cpp",
"*.ush": "hlsl",
"xstring": "cpp", "xstring": "cpp",
"list": "cpp", "list": "cpp",
"xhash": "cpp", "xhash": "cpp",
@@ -93,7 +94,18 @@
"shared_mutex": "cpp", "shared_mutex": "cpp",
"unordered_set": "cpp", "unordered_set": "cpp",
"csetjmp": "cpp", "csetjmp": "cpp",
"memory_resource": "cpp" "memory_resource": "cpp",
"*.inc": "cpp",
"any": "cpp",
"bit": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"compare": "cpp",
"execution": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
"scoped_allocator": "cpp",
"stack": "cpp"
}, },
"cmake.generator": "Ninja", "cmake.generator": "Ninja",
"cmake.skipConfigureIfCachePresent": false, "cmake.skipConfigureIfCachePresent": false,
+1 -1
+2 -2
View File
@@ -10,7 +10,7 @@ struct ComputeShaderInput
uint groupIndex : SV_GroupIndex; uint groupIndex : SV_GroupIndex;
}; };
layout(set = 0, binding = 0) layout(set = 0, binding = 0, std430)
cbuffer DispatchParams cbuffer DispatchParams
{ {
uint3 numThreadGroups; uint3 numThreadGroups;
@@ -18,7 +18,7 @@ cbuffer DispatchParams
uint3 numThreads; uint3 numThreads;
uint pad1; uint pad1;
} }
layout(set = 0, binding = 2) layout(set = 0, binding = 2, std430)
RWStructuredBuffer<Frustum> out_Frustums; RWStructuredBuffer<Frustum> out_Frustums;
+21 -9
View File
@@ -1,4 +1,6 @@
import InputGeometry; import Material;
import VERTEX_INPUT_IMPORT;
import MATERIAL_IMPORT;
struct ViewParams struct ViewParams
{ {
@@ -10,6 +12,11 @@ struct ViewParams
layout(set = 0, binding = 0) layout(set = 0, binding = 0)
ParameterBlock<ViewParams> gViewParams; ParameterBlock<ViewParams> gViewParams;
layout(set = 1)
type_param TMaterial : IMaterial;
ParameterBlock<TMaterial> gMaterial;
struct ModelParameter struct ModelParameter
{ {
float4x4 modelMatrix; float4x4 modelMatrix;
@@ -18,16 +25,21 @@ struct ModelParameter
[[vk::push_constant]] [[vk::push_constant]]
ConstantBuffer<ModelParameter> gModelParams; ConstantBuffer<ModelParameter> gModelParams;
struct VertexShaderOutput struct VertexStageOutput
{ {
float4 out_Position : SV_Position; float4 position : SV_Position;
} }
[shader("vertex")] [shader("vertex")]
VertexShaderOutput depthPrepass(PositionOnlyVertexInput input) VertexStageOutput vertexMain(PositionOnlyVertexShaderInput input)
{ {
VertexShaderOutput out; VertexStageOutput output;
float4 worldPos = mul(gModelParams.modelMatrix, float4(input.getVertexPosition(), 1));
float4 viewPos = mul(gViewParams.viewMatrix, worldPos); float3 worldPosition = input.getWorldPosition();
out.out_Position = mul(gViewParams.projectionMatrix, viewPos); worldPosition += gMaterial.getWorldOffset();
return out; float4 clipSpacePosition;
float4 viewSpacePosition = mul(gViewParams.viewMatrix, float4(worldPosition, 1));
clipSpacePosition = mul(gViewParams.projectionMatrix, viewSpacePosition);
output.position = clipSpacePosition;
return output;
} }
+8 -9
View File
@@ -1,11 +1,10 @@
import LightEnv; import LightEnv;
import BRDF; import BRDF;
import Material; import Material;
import TexturedMaterial;
import FlatColorMaterial;
import Common; import Common;
//TODO revert to pre processed shader attributes
import StaticMeshShaderAttributes; import VERTEX_INPUT_IMPORT;
import MATERIAL_IMPORT;
import PrimitiveSceneData; import PrimitiveSceneData;
import MaterialParameter; import MaterialParameter;
@@ -14,9 +13,9 @@ import MaterialParameter;
//layout(set = 0, binding = 3) //layout(set = 0, binding = 3)
//RWTexture2D<uint2> lightGrid; //RWTexture2D<uint2> lightGrid;
layout(set = 1, std430) type_param TMaterial : IMaterial;
//type_param TMaterial : IMaterial; layout(set = 1)
ParameterBlock<TexturedMaterial> gMaterial; ParameterBlock<TMaterial> gMaterial;
struct VertexStageOutput struct VertexStageOutput
{ {
@@ -31,7 +30,7 @@ VertexStageOutput vertexMain(
{ {
VertexStageOutput output; VertexStageOutput output;
VertexValueCache cache = input.getVertexCache(); VertexValueCache cache = input.getVertexCache();
float3 worldPosition = input.getWorldPosition(cache); float3 worldPosition = input.getWorldPosition();
float4 clipSpacePosition; float4 clipSpacePosition;
float3x3 tangentToLocal = cache.tangentToLocal; float3x3 tangentToLocal = cache.tangentToLocal;
@@ -52,7 +51,7 @@ float4 fragmentMain(
) : SV_Target ) : SV_Target
{ {
MaterialFragmentParameter materialParams = input.getMaterialParameter(position); MaterialFragmentParameter materialParams = input.getMaterialParameter(position);
BlinnPhong brdf = gMaterial.prepare(materialParams); TMaterial.BRDF brdf = gMaterial.prepare(materialParams);
float3 viewDir = normalize(materialParams.viewDir); float3 viewDir = normalize(materialParams.viewDir);
@@ -50,26 +50,51 @@
"clearCoatGloss": { "clearCoatGloss": {
"type": "float", "type": "float",
"default": "1.0f" "default": "1.0f"
},
"worldOffset": {
"type": "float3",
"default": "float3(0, 0, 0)"
}, },
"textureSampler": { "textureSampler": {
"type": "SamplerState" "type": "SamplerState"
} }
}, },
"code": [ "code": {
"result.baseColor = diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;", "baseColor": [
"result.metallic = 0;", "return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;"
"float3 bumpMapNormal = normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;", ],
"bumpMapNormal = 2.0 * bumpMapNormal - float3(1.0, 1.0, 1.0);", "metallic": [
"result.normal = input.transformLocalToWorld(bumpMapNormal);", "return 0;"
"result.specular = specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;", ],
"result.roughness = roughness;", "normal": [
"result.specularTint = specularTint;", "return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;"
"result.anisotropic = anisotropic;", ],
"result.sheen = sheen;", "specular": [
"result.sheenTint = sheenTint;", "return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;"
"result.clearCoat = clearCoat;", ],
"result.clearCoatGloss = clearCoatGloss;", "roughness": [
"return result;" "return roughness;"
] ],
"specularTint": [
"return specularTint;"
],
"anisotropic": [
"return anisotropic;"
],
"sheen": [
"return sheen;"
],
"sheenTint": [
"return sheenTint;"
],
"clearCoat": [
"return clearCoat;"
],
"clearCoatGloss": [
"return clearCoatGloss;"
],
"worldOffset": [
"return worldOffset;"
]
}
} }
+1 -7
View File
@@ -10,15 +10,9 @@ struct BlinnPhong : IBRDF
float3 baseColor; float3 baseColor;
float metallic = 0; float metallic = 0;
float3 normal = float3(0, 1, 0); float3 normal = float3(0, 1, 0);
float subsurface = 0;
float specular = 0.5; float specular = 0.5;
float roughness = 0.5; float roughness = 0.5;
float specularTint = 0; float sheen = 1.f;
float anisotropic = 0;
float sheen = 0;
float sheenTint = 0.5f;
float clearCoat = 0;
float clearCoatGloss = 1;
float3 evaluate(float3 view, float3 light, float3 surfaceNormal, float3 tangent, float3 biTangent, float3 lightColor) float3 evaluate(float3 view, float3 light, float3 surfaceNormal, float3 tangent, float3 biTangent, float3 lightColor)
{ {
+2 -3
View File
@@ -1,11 +1,10 @@
import StaticMeshShaderAttributes;
import MaterialParameter; import MaterialParameter;
import BRDF; import BRDF;
import Common; import Common;
interface ILightEnv interface ILightEnv
{ {
float3 illuminate<B:IBRDF>(VertexShaderInput input, B brdf, float3 wo); float3 illuminate<B:IBRDF>(MaterialFragmentParameter input, B brdf, float3 wo);
}; };
struct DirectionalLight : ILightEnv struct DirectionalLight : ILightEnv
@@ -70,5 +69,5 @@ struct Lights
uint numPointLights; uint numPointLights;
}; };
layout(set = 0, binding = 1, std430) layout(set = 0, binding = 1)
ConstantBuffer<Lights> gLightEnv; ConstantBuffer<Lights> gLightEnv;
+9
View File
@@ -6,4 +6,13 @@ interface IMaterial
{ {
associatedtype BRDF : IBRDF; associatedtype BRDF : IBRDF;
BRDF prepare(MaterialFragmentParameter input); BRDF prepare(MaterialFragmentParameter input);
float3 getWorldOffset();
float3 getBaseColor(MaterialFragmentParameter input);
float getMetallic(MaterialFragmentParameter input);
float3 getNormal(MaterialFragmentParameter input);
float getSpecular(MaterialFragmentParameter input);
float getRoughness(MaterialFragmentParameter input);
float getSheen(MaterialFragmentParameter input);
}; };
+9 -2
View File
@@ -5,7 +5,7 @@ struct MaterialVertexParameter
#if NUM_MATERIAL_TEXCOORDS #if NUM_MATERIAL_TEXCOORDS
float2 texCoords[NUM_MATERIAL_TEXCOORDS]; float2 texCoords[NUM_MATERIAL_TEXCOORDS];
#endif #endif
#if USE_INSTANCING #ifdef USE_INSTANCING
float4x4 instanceLocalToWorld; float4x4 instanceLocalToWorld;
float3 instanceLocalPosition; float3 instanceLocalPosition;
float4 perInstanceParams; float4 perInstanceParams;
@@ -26,7 +26,7 @@ struct MaterialFragmentParameter
float4 clipPosition; float4 clipPosition;
float4 vertexColor; float4 vertexColor;
float3x3 tangentToWorld; float3x3 tangentToWorld;
#if USE_INSTANCING #ifdef USE_INSTANCING
float3 perInstanceParams; float3 perInstanceParams;
#endif #endif
#if NUM_MATERIAL_TEXCOORDS #if NUM_MATERIAL_TEXCOORDS
@@ -37,4 +37,11 @@ struct MaterialFragmentParameter
float3 result = mul(tangentToWorld, tangentSpaceNormal); float3 result = mul(tangentToWorld, tangentSpaceNormal);
return result; return result;
} }
float3 transformNormalTexture(float3 rawNormal)
{
rawNormal = 2.0 * rawNormal - float3(1.0, 1.0, 1.0);
return transformNormalToWorld(rawNormal);
}
}; };
@@ -114,7 +114,7 @@ struct VertexShaderInput
return result; return result;
} }
float3 getWorldPosition(VertexValueCache cache) float3 getWorldPosition()
{ {
float4x4 localToWorld = gSceneData.localToWorld; float4x4 localToWorld = gSceneData.localToWorld;
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz; float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
@@ -191,4 +191,10 @@ struct PositionOnlyVertexShaderInput
float3 instanceTransform2; float3 instanceTransform2;
float3 instanceTransform3; float3 instanceTransform3;
#endif // USE_INSTANCING #endif // USE_INSTANCING
float3 getWorldPosition()
{
float4x4 localToWorld = gSceneData.localToWorld;
float3 rotatedPosition = localToWorld[0].xyz * position.xxx + localToWorld[1].xyz * position.yyy + localToWorld[2].xyz * position.zzz;
return rotatedPosition + localToWorld[3].xyz;
}
}; };
+15 -5
View File
@@ -1,4 +1,5 @@
#include "Asset.h" #include "Asset.h"
#include "AssetRegistry.h"
using namespace Seele; using namespace Seele;
@@ -11,9 +12,18 @@ Asset::Asset()
{ {
} }
Asset::Asset(const std::filesystem::path& path) Asset::Asset(const std::filesystem::path& path)
: fullPath(std::filesystem::absolute(path)) : status(Status::Uninitialized)
, status(Status::Uninitialized)
{ {
if(path.is_absolute())
{
fullPath = path;
}
else
{
fullPath = AssetRegistry::getRootFolder();
fullPath.append(path.generic_string());
}
fullPath.make_preferred(); fullPath.make_preferred();
parentDir = fullPath.parent_path(); parentDir = fullPath.parent_path();
name = fullPath.stem(); name = fullPath.stem();
@@ -49,15 +59,15 @@ std::ofstream &Asset::getWriteStream()
return outStream; return outStream;
} }
std::string Asset::getFileName() std::string Asset::getFileName() const
{ {
return name.generic_string(); return name.generic_string();
} }
std::string Asset::getFullPath() std::string Asset::getFullPath() const
{ {
return fullPath.generic_string(); return fullPath.generic_string();
} }
std::string Asset::getExtension() std::string Asset::getExtension() const
{ {
return extension.generic_string(); return extension.generic_string();
} }
+4 -3
View File
@@ -23,11 +23,11 @@ public:
virtual void load() = 0; virtual void load() = 0;
// returns the name of the file, without extension // returns the name of the file, without extension
std::string getFileName(); std::string getFileName() const;
// returns the full absolute path, from root to extension // returns the full absolute path, from root to extension
std::string getFullPath(); std::string getFullPath() const;
// returns the file extension, without preceding dot // returns the file extension, without preceding dot
std::string getExtension(); std::string getExtension() const;
inline Status getStatus() inline Status getStatus()
{ {
std::scoped_lock lck(lock); std::scoped_lock lck(lock);
@@ -44,6 +44,7 @@ protected:
std::ofstream& getWriteStream(); std::ofstream& getWriteStream();
private: private:
Status status; Status status;
// Path relative to the project root
std::filesystem::path fullPath; std::filesystem::path fullPath;
std::filesystem::path parentDir; std::filesystem::path parentDir;
std::filesystem::path name; std::filesystem::path name;
+48 -6
View File
@@ -28,16 +28,16 @@ void AssetRegistry::importFile(const std::string &filePath)
if (extension.compare(".fbx") == 0 if (extension.compare(".fbx") == 0
|| extension.compare(".obj") == 0) || extension.compare(".obj") == 0)
{ {
get().registerMesh(fsPath); get().importMesh(fsPath);
} }
if (extension.compare(".png") == 0 if (extension.compare(".png") == 0
|| extension.compare(".jpg") == 0) || extension.compare(".jpg") == 0)
{ {
get().registerTexture(fsPath); get().importTexture(fsPath);
} }
if (extension.compare(".semat") == 0) if (extension.compare(".semat") == 0)
{ {
get().registerMaterial(fsPath); get().importMaterial(fsPath);
} }
} }
@@ -51,6 +51,16 @@ PMaterialAsset AssetRegistry::findMaterial(const std::string &filePath)
return get().materials[filePath]; return get().materials[filePath];
} }
std::ofstream AssetRegistry::createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
{
return get().internalCreateWriteStream(relativePath, openmode);
}
std::ifstream AssetRegistry::createReadStream(const std::string& relativePath, std::ios_base::openmode openmode)
{
return get().internalCreateReadStream(relativePath, openmode);
}
PTextureAsset AssetRegistry::findTexture(const std::string &filePath) PTextureAsset AssetRegistry::findTexture(const std::string &filePath)
{ {
return get().textures[filePath]; return get().textures[filePath];
@@ -75,17 +85,49 @@ void AssetRegistry::init(const std::filesystem::path &rootFolder, Gfx::PGraphics
reg.materialLoader = new MaterialLoader(graphics); reg.materialLoader = new MaterialLoader(graphics);
} }
void AssetRegistry::registerMesh(const std::filesystem::path &filePath) std::string AssetRegistry::getRootFolder()
{
return get().rootFolder.generic_string();
}
void AssetRegistry::importMesh(const std::filesystem::path &filePath)
{ {
meshLoader->importAsset(filePath); meshLoader->importAsset(filePath);
} }
void AssetRegistry::registerTexture(const std::filesystem::path &filePath) void AssetRegistry::importTexture(const std::filesystem::path &filePath)
{ {
textureLoader->importAsset(filePath); textureLoader->importAsset(filePath);
} }
void AssetRegistry::registerMaterial(const std::filesystem::path &filePath) void AssetRegistry::importMaterial(const std::filesystem::path &filePath)
{ {
materialLoader->queueAsset(filePath); materialLoader->queueAsset(filePath);
} }
void AssetRegistry::registerMesh(PMeshAsset mesh)
{
PMeshAsset existingMesh = meshes[mesh->getFileName()];
if(existingMesh != nullptr)
{
auto newMeshes = mesh->getMeshes();
for(uint32 i = 0; i < newMeshes.size(); ++i)
{
existingMesh->addMesh(newMeshes[i]);
}
}
else
{
meshes[mesh->getFileName()] = mesh;
}
}
std::ofstream AssetRegistry::internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode)
{
return std::ofstream(rootFolder.generic_string().append(relativePath), openmode);
}
std::ifstream AssetRegistry::internalCreateReadStream(const std::string& relativePath, std::ios_base::openmode openmode)
{
return std::ifstream(rootFolder.generic_string().append(relativePath), openmode);
}
+15 -3
View File
@@ -18,20 +18,32 @@ public:
~AssetRegistry(); ~AssetRegistry();
static void init(const std::string& rootFolder); static void init(const std::string& rootFolder);
static std::string getRootFolder();
static void importFile(const std::string& filePath); static void importFile(const std::string& filePath);
static PMeshAsset findMesh(const std::string& filePath); static PMeshAsset findMesh(const std::string& filePath);
static PTextureAsset findTexture(const std::string& filePath); static PTextureAsset findTexture(const std::string& filePath);
static PMaterialAsset findMaterial(const std::string& filePath); static PMaterialAsset findMaterial(const std::string& filePath);
static std::ofstream createWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = 0);
static std::ifstream createReadStream(const std::string& relativePath, std::ios_base::openmode openmode = 0);
private: private:
static AssetRegistry& get(); static AssetRegistry& get();
AssetRegistry(); AssetRegistry();
void init(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics); void init(const std::filesystem::path& rootFolder, Gfx::PGraphics graphics);
void registerMesh(const std::filesystem::path& filePath); void importMesh(const std::filesystem::path& filePath);
void registerTexture(const std::filesystem::path& filePath); void importTexture(const std::filesystem::path& filePath);
void registerMaterial(const std::filesystem::path& filePath); void importMaterial(const std::filesystem::path& filePath);
void registerMesh(PMeshAsset mesh);
void registerTexture(PTextureAsset texture);
void registerMaterial(PMaterialAsset material);
std::ofstream internalCreateWriteStream(const std::string& relativePath, std::ios_base::openmode openmode = 0);
std::ifstream internalCreateReadStream(const std::string& relaitvePath, std::ios_base::openmode openmode = 0);
std::filesystem::path rootFolder; std::filesystem::path rootFolder;
Map<std::string, PTextureAsset> textures; Map<std::string, PTextureAsset> textures;
+5 -1
View File
@@ -5,9 +5,11 @@
using namespace Seele; using namespace Seele;
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics) MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
: graphics(graphics)
{ {
placeholderMaterial = new Material("shaders/Placeholder.semat"); placeholderMaterial = new Material(std::filesystem::absolute("./shaders/Placeholder.asset"));
placeholderMaterial->compile(); placeholderMaterial->compile();
graphics->getShaderCompiler()->registerMaterial(placeholderMaterial);
} }
MaterialLoader::~MaterialLoader() MaterialLoader::~MaterialLoader()
@@ -17,6 +19,8 @@ MaterialLoader::~MaterialLoader()
PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath) PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath)
{ {
PMaterial result = new Material(filePath); PMaterial result = new Material(filePath);
result->compile();
graphics->getShaderCompiler()->registerMaterial(result);
// TODO: There is actually no real reason to import a standalone material, // TODO: There is actually no real reason to import a standalone material,
// maybe in the future there could be a substance loader or something // maybe in the future there could be a substance loader or something
return result; return result;
+1
View File
@@ -16,6 +16,7 @@ public:
~MaterialLoader(); ~MaterialLoader();
PMaterial queueAsset(const std::filesystem::path& filePath); PMaterial queueAsset(const std::filesystem::path& filePath);
private: private:
Gfx::PGraphics graphics;
List<std::future<void>> futures; List<std::future<void>> futures;
PMaterial placeholderMaterial; PMaterial placeholderMaterial;
}; };
+42 -37
View File
@@ -3,9 +3,11 @@
#include "Graphics/Graphics.h" #include "Graphics/Graphics.h"
#include "MeshAsset.h" #include "MeshAsset.h"
#include "Graphics/Mesh.h" #include "Graphics/Mesh.h"
#include "Graphics/StaticMeshVertexInput.h"
#include "AssetRegistry.h" #include "AssetRegistry.h"
#include "Material/Material.h" #include "Material/Material.h"
#include <fstream> #include <fstream>
#include <iostream>
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <stb_image_write.h> #include <stb_image_write.h>
#include <assimp/config.h> #include <assimp/config.h>
@@ -27,7 +29,8 @@ MeshLoader::~MeshLoader()
void MeshLoader::importAsset(const std::filesystem::path &path) void MeshLoader::importAsset(const std::filesystem::path &path)
{ {
futures.add(std::async(std::launch::async, &MeshLoader::import, this, path)); //futures.add(std::async(std::launch::async, &MeshLoader::import, this, path));
import(path);
} }
void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics) void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials, Gfx::PGraphics graphics)
@@ -52,7 +55,7 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
matCode["params"]["diffuseTexture"] = matCode["params"]["diffuseTexture"] =
{ {
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texFilename} {"default", texPath.C_Str()}
}; };
code.push_back("result.baseColor = diffuseTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); code.push_back("result.baseColor = diffuseTexture.Sample(textureSampler, geometry.texCoord).xyz;\n");
} }
@@ -62,7 +65,7 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
matCode["params"]["specularTexture"] = matCode["params"]["specularTexture"] =
{ {
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texFilename} {"default", texPath.C_Str()}
}; };
code.push_back("result.specular = specularTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); code.push_back("result.specular = specularTexture.Sample(textureSampler, geometry.texCoord).xyz;\n");
} }
@@ -72,7 +75,7 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
matCode["params"]["normalTexture"] = matCode["params"]["normalTexture"] =
{ {
{"type", "Texture2D"}, {"type", "Texture2D"},
{"default", texFilename} {"default", texPath.C_Str()}
}; };
code.push_back("float3 bumpMapNormal = normalTexture.Sample(textureSampler, geometry.texCoord).xyz;\n"); code.push_back("float3 bumpMapNormal = normalTexture.Sample(textureSampler, geometry.texCoord).xyz;\n");
code.push_back("bumpMapNormal = 2.0 * bumpMapNormal - float3(1.0f, 1.0f, 1.0f);\n"); code.push_back("bumpMapNormal = 2.0 * bumpMapNormal - float3(1.0f, 1.0f, 1.0f);\n");
@@ -80,10 +83,15 @@ void loadMaterials(const aiScene* scene, Array<PMaterialAsset>& globalMaterials,
} }
code.push_back("return result;\n"); code.push_back("return result;\n");
matCode["code"] = code; matCode["code"] = code;
std::ofstream outMatFile("testMat.asset"); std::string outMatFilename = matCode["name"].get<std::string>().append(".asset");
std::ofstream outMatFile = AssetRegistry::createWriteStream(outMatFilename);
outMatFile << std::setw(4) << matCode; outMatFile << std::setw(4) << matCode;
outMatFile.flush(); outMatFile.flush();
PMaterial asset = new Material("testMat.asset"); outMatFile.close();
//TODO: let the material loader handle this instead
std::cout << matCode["name"] << std::endl;
AssetRegistry::importFile(outMatFilename);
PMaterialAsset asset = AssetRegistry::findMaterial(outMatFilename);
globalMaterials[i] = asset; globalMaterials[i] = asset;
} }
} }
@@ -108,7 +116,7 @@ void loadToBuffer(Array<Vector>& buffer, const aiVector3D* sourceData, uint32 si
buffer[i] = Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z); buffer[i] = Vector(sourceData[i].x, sourceData[i].y, sourceData[i].z);
} }
} }
Gfx::VertexStream createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics) VertexStreamComponent createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::PGraphics graphics)
{ {
Array<Vector> buffer(size); Array<Vector> buffer(size);
for(uint32 i = 0; i < size; ++i) for(uint32 i = 0; i < size; ++i)
@@ -121,12 +129,10 @@ Gfx::VertexStream createVertexStream(uint32 size, aiVector3D* sourceData, Gfx::P
vbInfo.resourceData.data = (uint8 *)buffer.data(); vbInfo.resourceData.data = (uint8 *)buffer.data();
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
vbInfo.resourceData.size = buffer.size(); vbInfo.resourceData.size = buffer.size();
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo); const Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
auto stream = Gfx::VertexStream(vbInfo.vertexSize, 0, false, vertexBuffer); return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32B32_SFLOAT);
stream.addVertexElement(Gfx::VertexElement(0, Gfx::SE_FORMAT_R32G32_SFLOAT, 0));
return stream;
} }
Gfx::VertexStream createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics) VertexStreamComponent createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::PGraphics graphics)
{ {
Array<Vector2> buffer(size); Array<Vector2> buffer(size);
for(uint32 i = 0; i < size; ++i) for(uint32 i = 0; i < size; ++i)
@@ -140,9 +146,7 @@ Gfx::VertexStream createVertexStream(uint32 size, aiVector2D* sourceData, Gfx::P
vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER; vbInfo.resourceData.owner = Gfx::QueueType::DEDICATED_TRANSFER;
vbInfo.resourceData.size = buffer.size(); vbInfo.resourceData.size = buffer.size();
Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo); Gfx::PVertexBuffer vertexBuffer = graphics->createVertexBuffer(vbInfo);
auto stream = Gfx::VertexStream(vbInfo.vertexSize, 0, false, vertexBuffer); return VertexStreamComponent(vertexBuffer, 0, vbInfo.vertexSize, Gfx::SE_FORMAT_R32G32_SFLOAT);
stream.addVertexElement(Gfx::VertexElement(0, Gfx::SE_FORMAT_R32G32B32_SFLOAT, 0));
return stream;
} }
void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PMaterialAsset> materials, Gfx::PGraphics graphics) void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PMaterialAsset> materials, Gfx::PGraphics graphics)
{ {
@@ -150,32 +154,29 @@ void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PM
{ {
aiMesh *mesh = scene->mMeshes[meshIndex]; aiMesh *mesh = scene->mMeshes[meshIndex];
MeshDescription description; PStaticMeshVertexInput vertexShaderInput = new StaticMeshVertexInput(std::string(mesh->mName.C_Str()));
Gfx::PVertexDeclaration declaration = new Gfx::VertexDeclaration(); VertexStreamComponent positionStream = createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics);
declaration->addVertexStream(createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics)); vertexShaderInput->setPositionStream(positionStream);
description.layout.add(Gfx::VertexAttribute::POSITION);
for(uint32 i = 0; i < MAX_TEX_CHANNELS; ++i) for(uint32 i = 0; i < MAX_TEXCOORDS; ++i)
{ {
if(mesh->HasTextureCoords(i)) if(mesh->HasTextureCoords(i))
{ {
declaration->addVertexStream(createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics)); VertexStreamComponent texCoordStream = createVertexStream(mesh->mNumVertices, mesh->mTextureCoords[i], graphics);
description.layout.add(Gfx::VertexAttribute::TEXCOORD); vertexShaderInput->setTexCoordStream(i, texCoordStream);
} }
} }
if(mesh->HasNormals()) if(mesh->HasNormals())
{ {
declaration->addVertexStream(createVertexStream(mesh->mNumVertices, mesh->mNormals, graphics)); VertexStreamComponent normalStream = createVertexStream(mesh->mNumVertices, mesh->mNormals, graphics);
description.layout.add(Gfx::VertexAttribute::NORMAL); vertexShaderInput->setTangentXStream(normalStream);
} }
if(mesh->HasTangentsAndBitangents()) if(mesh->HasTangentsAndBitangents())
{ {
declaration->addVertexStream(createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics)); //TODO: use bitangent to calculate sign for 4th coordinate of tangentstream
declaration->addVertexStream(createVertexStream(mesh->mNumVertices, mesh->mVertices, graphics)); VertexStreamComponent tangentStream = createVertexStream(mesh->mNumVertices, mesh->mTangents, graphics);
description.layout.add(Gfx::VertexAttribute::TANGENT); vertexShaderInput->setTangentZStream(tangentStream);
description.layout.add(Gfx::VertexAttribute::BITANGENT);
} }
description.declaration = declaration;
Array<uint32> indices(mesh->mNumFaces * 3); Array<uint32> indices(mesh->mNumFaces * 3);
for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex) for (uint32 faceIndex = 0; faceIndex < mesh->mNumFaces; ++faceIndex)
@@ -192,7 +193,7 @@ void loadGlobalMeshes(const aiScene* scene, Array<PMesh>& globalMeshes, Array<PM
Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo); Gfx::PIndexBuffer indexBuffer = graphics->createIndexBuffer(idxInfo);
indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS); indexBuffer->transferOwnership(Gfx::QueueType::GRAPHICS);
globalMeshes[meshIndex] = new Mesh(description, indexBuffer); globalMeshes[meshIndex] = new Mesh(vertexShaderInput, indexBuffer);
globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex]; globalMeshes[meshIndex]->referencedMaterial = materials[mesh->mMaterialIndex];
} }
} }
@@ -247,23 +248,27 @@ void MeshLoader::import(const std::filesystem::path &path)
aiProcess_FindDegenerates | aiProcess_FindDegenerates |
aiProcess_EmbedTextures); aiProcess_EmbedTextures);
const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace); const aiScene *scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
Array<PMesh> globalMeshes(scene->mNumMeshes);
Array<PMaterialAsset> globalMaterials(scene->mNumMaterials); Array<PMaterialAsset> globalMaterials(scene->mNumMaterials);
loadMaterials(scene, globalMaterials, graphics);
loadGlobalMeshes(scene, globalMeshes, globalMaterials, graphics);
loadTextures(scene, graphics, path); loadTextures(scene, graphics, path);
loadMaterials(scene, globalMaterials, graphics);
Array<PMesh> globalMeshes(scene->mNumMeshes);
loadGlobalMeshes(scene, globalMeshes, globalMaterials, graphics);
List<aiNode *> meshNodes; List<aiNode *> meshNodes;
findMeshRoots(scene->mRootNode, meshNodes); findMeshRoots(scene->mRootNode, meshNodes);
std::filesystem::path filePath = path.filename();
filePath.replace_extension("asset");
PMeshAsset meshAsset = new MeshAsset(filePath.generic_string());
for (auto meshNode : meshNodes) for (auto meshNode : meshNodes)
{ {
std::string fileName = std::string("arissa").append(".asset");
PMeshAsset meshAsset = new MeshAsset(fileName);
for(uint32 i = 0; i < meshNode->mNumMeshes; ++i) for(uint32 i = 0; i < meshNode->mNumMeshes; ++i)
{ {
meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]); meshAsset->addMesh(globalMeshes[meshNode->mMeshes[i]]);
} }
meshAsset->save();
AssetRegistry::get().meshes[meshAsset->getFileName()] = meshAsset;
} }
meshAsset->save();
AssetRegistry::get().registerMesh(meshAsset);
} }
+13 -11
View File
@@ -12,8 +12,7 @@ using namespace Seele;
TextureLoader::TextureLoader(Gfx::PGraphics graphics) TextureLoader::TextureLoader(Gfx::PGraphics graphics)
: graphics(graphics) : graphics(graphics)
{ {
import("textures/placeholder.png"); placeholderTexture = import("./textures/placeholder.png");
placeholderTexture = AssetRegistry::findTexture("textures/placeholder.png");
} }
TextureLoader::~TextureLoader() TextureLoader::~TextureLoader()
@@ -22,15 +21,20 @@ TextureLoader::~TextureLoader()
void TextureLoader::importAsset(const std::filesystem::path& filePath) void TextureLoader::importAsset(const std::filesystem::path& filePath)
{ {
futures.add(std::async(std::launch::async, &TextureLoader::import, this, filePath)); auto assetFileName = filePath;
PTextureAsset asset = new TextureAsset(assetFileName.replace_extension("asset").filename().generic_string());
asset->setStatus(Asset::Status::Loading);
asset->setTexture(placeholderTexture);
AssetRegistry::get().textures[filePath.string()] = asset;
futures.add(std::async(std::launch::async, [this, filePath, asset] () mutable {
Gfx::PTexture2D texture = import(filePath);
asset->setTexture(texture);
asset->setStatus(Asset::Status::Ready);
}));
} }
void TextureLoader::import(const std::filesystem::path& path) Gfx::PTexture2D TextureLoader::import(const std::filesystem::path& path)
{ {
auto assetFileName = path;
std::filesystem::path assetPath = AssetRegistry::get().rootFolder.append(assetFileName.replace_extension("asset").filename().string());
PTextureAsset asset = new TextureAsset(assetPath);
asset->setStatus(Asset::Status::Loading);
int x, y, n; int x, y, n;
unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4); unsigned char* data = stbi_load(path.string().c_str(), &x, &y, &n, 4);
TextureCreateInfo createInfo; TextureCreateInfo createInfo;
@@ -43,7 +47,5 @@ void TextureLoader::import(const std::filesystem::path& path)
Gfx::PTexture2D texture = graphics->createTexture2D(createInfo); Gfx::PTexture2D texture = graphics->createTexture2D(createInfo);
stbi_image_free(data); stbi_image_free(data);
texture->transferOwnership(Gfx::QueueType::GRAPHICS); texture->transferOwnership(Gfx::QueueType::GRAPHICS);
asset->setTexture(texture); return texture;
asset->setStatus(Asset::Status::Ready);
AssetRegistry::get().textures[path.string()] = asset;
} }
+3 -2
View File
@@ -9,6 +9,7 @@ namespace Seele
{ {
DECLARE_REF(TextureAsset); DECLARE_REF(TextureAsset);
DECLARE_NAME_REF(Gfx, Graphics); DECLARE_NAME_REF(Gfx, Graphics);
DECLARE_NAME_REF(Gfx, Texture2D);
class TextureLoader class TextureLoader
{ {
public: public:
@@ -16,10 +17,10 @@ public:
~TextureLoader(); ~TextureLoader();
void importAsset(const std::filesystem::path& filePath); void importAsset(const std::filesystem::path& filePath);
private: private:
void import(const std::filesystem::path& path); Gfx::PTexture2D import(const std::filesystem::path& path);
Gfx::PGraphics graphics; Gfx::PGraphics graphics;
List<std::future<void>> futures; List<std::future<void>> futures;
PTextureAsset placeholderTexture; Gfx::PTexture2D placeholderTexture;
}; };
DEFINE_REF(TextureLoader); DEFINE_REF(TextureLoader);
} // namespace Seele } // namespace Seele
+8 -1
View File
@@ -163,7 +163,14 @@ public:
{ {
prev->next = next; prev->next = next;
} }
next->prev = prev; if(next == nullptr)
{
root = prev;
}
else
{
next->prev = prev;
}
delete pos.node; delete pos.node;
refreshIterators(); refreshIterators();
return Iterator(next); return Iterator(next);
+6
View File
@@ -11,16 +11,22 @@ target_sources(SeeleEngine
MeshBatch.h MeshBatch.h
RenderCore.h RenderCore.h
RenderCore.cpp RenderCore.cpp
RenderMaterial.h
RenderMaterial.cpp
RenderPath.h RenderPath.h
RenderPath.cpp RenderPath.cpp
SceneView.h SceneView.h
SceneView.cpp SceneView.cpp
SceneRenderPath.h SceneRenderPath.h
SceneRenderPath.cpp SceneRenderPath.cpp
ShaderCompiler.h
ShaderCompiler.cpp
View.h View.h
View.cpp View.cpp
VertexShaderInput.h VertexShaderInput.h
VertexShaderInput.cpp VertexShaderInput.cpp
StaticMeshVertexInput.h
StaticMeshVertexInput.cpp
Window.cpp Window.cpp
Window.h Window.h
WindowManager.h WindowManager.h
+2 -1
View File
@@ -1,10 +1,11 @@
#include "Graphics.h" #include "Graphics.h"
#include <map> #include "ShaderCompiler.h"
using namespace Seele::Gfx; using namespace Seele::Gfx;
Graphics::Graphics() Graphics::Graphics()
{ {
shaderCompiler = new ShaderCompiler(this);
} }
Graphics::~Graphics() Graphics::~Graphics()
+7
View File
@@ -3,6 +3,7 @@
#include "GraphicsResources.h" #include "GraphicsResources.h"
#include "Containers/Array.h" #include "Containers/Array.h"
#include "VertexShaderInput.h" #include "VertexShaderInput.h"
#include "ShaderCompiler.h"
namespace Seele namespace Seele
{ {
@@ -20,6 +21,11 @@ public:
return queueMapping; return queueMapping;
} }
PShaderCompiler getShaderCompiler() const
{
return shaderCompiler;
}
virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0; virtual PWindow createWindow(const WindowCreateInfo &createInfo) = 0;
virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0; virtual PViewport createViewport(PWindow owner, const ViewportCreateInfo &createInfo) = 0;
@@ -47,6 +53,7 @@ public:
protected: protected:
QueueFamilyMapping queueMapping; QueueFamilyMapping queueMapping;
PShaderCompiler shaderCompiler;
friend class Window; friend class Window;
}; };
DEFINE_REF(Graphics); DEFINE_REF(Graphics);
@@ -100,6 +100,7 @@ struct ShaderCreateInfo
Array<std::string> shaderCode; Array<std::string> shaderCode;
std::string entryPoint; std::string entryPoint;
Array<const char*> typeParameter; Array<const char*> typeParameter;
Map<const char*, const char*> defines;
}; };
namespace Gfx namespace Gfx
+47 -27
View File
@@ -42,18 +42,37 @@ ShaderCollection& ShaderMap::createShaders(
PGraphics graphics, PGraphics graphics,
RenderPassType renderPass, RenderPassType renderPass,
PMaterial material, PMaterial material,
PVertexShaderInput vertexInput, VertexInputType* vertexInput,
bool bPositionOnly) bool bPositionOnly)
{ {
ShaderCollection& collection = shaders.add(); ShaderCollection& collection = shaders.add();
collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration(); //collection.vertexDeclaration = bPositionOnly ? vertexInput->getPositionDeclaration() : vertexInput->getDeclaration();
ShaderCreateInfo createInfo; ShaderCreateInfo createInfo;
createInfo.entryPoint = "vertexMain"; createInfo.entryPoint = "vertexMain";
createInfo.typeParameter = {material->getMaterialName().c_str(), vertexInput->getName().c_str()}; createInfo.typeParameter = {material->getName().c_str()};
createInfo.defines["VERTEX_INPUT_IMPORT"] = vertexInput->getShaderFilename();
createInfo.defines["MATERIAL_IMPORT"] = material->getName().c_str();
createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1";
createInfo.defines["USE_INSTANCING"] = "0";
std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass), std::ios::ate);
auto fileSize = codeStream.tellg();
codeStream.seekg(0);
Array<char> buffer(static_cast<uint32>(fileSize));
codeStream.read(buffer.data(), fileSize);
createInfo.shaderCode.add(std::string(buffer.data()));
collection.vertexShader = graphics->createVertexShader(createInfo); collection.vertexShader = graphics->createVertexShader(createInfo);
if(renderPass != RenderPassType::DepthPrepass)
{
createInfo.entryPoint = "fragmentMain";
collection.fragmentShader = graphics->createFragmentShader(createInfo);
}
return collection; return collection;
} }
void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount) void DescriptorLayout::addDescriptorBinding(uint32 bindingIndex, SeDescriptorType type, uint32 arrayCount)
@@ -108,8 +127,8 @@ void PipelineLayout::addPushConstants(const SePushConstantRange &pushConstant)
pushConstants.add(pushConstant); pushConstants.add(pushConstant);
} }
QueueOwnedResource::QueueOwnedResource(PGraphics graphics, QueueType startQueueType) QueueOwnedResource::QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType)
: graphics(graphics) : mapping(mapping)
, currentOwner(startQueueType) , currentOwner(startQueueType)
{ {
} }
@@ -120,15 +139,15 @@ QueueOwnedResource::~QueueOwnedResource()
void QueueOwnedResource::transferOwnership(QueueType newOwner) void QueueOwnedResource::transferOwnership(QueueType newOwner)
{ {
if(graphics->getFamilyMapping().needsTransfer(currentOwner, newOwner)) if(mapping.needsTransfer(currentOwner, newOwner))
{ {
executeOwnershipBarrier(newOwner); executeOwnershipBarrier(newOwner);
currentOwner = newOwner; currentOwner = newOwner;
} }
} }
Buffer::Buffer(PGraphics graphics, QueueType startQueue) Buffer::Buffer(QueueFamilyMapping mapping, QueueType startQueue)
: QueueOwnedResource(graphics, startQueue) : QueueOwnedResource(mapping, startQueue)
{ {
} }
@@ -136,31 +155,32 @@ Buffer::~Buffer()
{ {
} }
UniformBuffer::UniformBuffer(PGraphics graphics, QueueType startQueueType) UniformBuffer::UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType)
: Buffer(graphics, startQueueType) : Buffer(mapping, startQueueType)
{ {
} }
UniformBuffer::~UniformBuffer() UniformBuffer::~UniformBuffer()
{ {
} }
StructuredBuffer::StructuredBuffer(PGraphics graphics, QueueType startQueueType) StructuredBuffer::StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType)
: Buffer(graphics, startQueueType) : Buffer(mapping, startQueueType)
{ {
} }
StructuredBuffer::~StructuredBuffer() StructuredBuffer::~StructuredBuffer()
{ {
} }
VertexBuffer::VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType) VertexBuffer::VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType)
: Buffer(graphics, startQueueType) : Buffer(mapping, startQueueType)
, numVertices(numVertices), vertexSize(vertexSize) , numVertices(numVertices)
, vertexSize(vertexSize)
{ {
} }
VertexBuffer::~VertexBuffer() VertexBuffer::~VertexBuffer()
{ {
} }
IndexBuffer::IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType) IndexBuffer::IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType indexType, QueueType startQueueType)
: Buffer(graphics, startQueueType) : Buffer(mapping, startQueueType)
, indexType(indexType) , indexType(indexType)
{ {
switch (indexType) switch (indexType)
@@ -179,8 +199,8 @@ IndexBuffer::~IndexBuffer()
} }
VertexStream::VertexStream() VertexStream::VertexStream()
{} {}
VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced, Gfx::PVertexBuffer vertexBuffer) VertexStream::VertexStream(uint32 stride, uint32 offset, uint8 instanced)
: stride(stride), instanced(instanced), offset(offset), vertexBuffer(vertexBuffer) : stride(stride), instanced(instanced), offset(offset)
{ {
} }
VertexStream::~VertexStream() VertexStream::~VertexStream()
@@ -200,19 +220,19 @@ VertexDeclaration::VertexDeclaration()
VertexDeclaration::~VertexDeclaration() VertexDeclaration::~VertexDeclaration()
{ {
} }
uint32 VertexDeclaration::addVertexStream(const VertexStream &element) uint32 VertexDeclaration::addVertexStream(const VertexStreamComponent &element)
{ {
uint32 currIndex = vertexStreams.size(); VertexStream& stream = vertexStreams.add();
vertexStreams.add(element); stream.addVertexElement(VertexElement(element.streamOffset, element.type, element.offset));
return currIndex; return stream.vertexDescription.size() - 1;
} }
const Array<VertexStream> &VertexDeclaration::getVertexStreams() const const Array<VertexStream> &VertexDeclaration::getVertexStreams() const
{ {
return vertexStreams; return vertexStreams;
} }
Texture::Texture(PGraphics graphics, Gfx::QueueType startQueueType) Texture::Texture(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: QueueOwnedResource(graphics, startQueueType) : QueueOwnedResource(mapping, startQueueType)
{ {
} }
@@ -220,8 +240,8 @@ Texture::~Texture()
{ {
} }
Texture2D::Texture2D(PGraphics graphics, Gfx::QueueType startQueueType) Texture2D::Texture2D(QueueFamilyMapping mapping, Gfx::QueueType startQueueType)
: Texture(graphics, startQueueType) : Texture(mapping, startQueueType)
{ {
} }
+30 -15
View File
@@ -6,13 +6,16 @@
#include "MeshBatch.h" #include "MeshBatch.h"
#include <boost/crc.hpp> #include <boost/crc.hpp>
#ifdef _DEBUG
#define ENABLE_VALIDATION #define ENABLE_VALIDATION
#ifdef DEBUG
#endif #endif
namespace Seele namespace Seele
{ {
struct VertexInputStream; struct VertexInputStream;
struct VertexStreamComponent;
class VertexInputType;
namespace Gfx namespace Gfx
{ {
DECLARE_REF(Graphics); DECLARE_REF(Graphics);
@@ -111,7 +114,7 @@ struct PermutationId
struct ShaderCollection struct ShaderCollection
{ {
PermutationId id; PermutationId id;
PVertexDeclaration vertexDeclaration; //PVertexDeclaration vertexDeclaration;
PVertexShader vertexShader; PVertexShader vertexShader;
PControlShader controlShader; PControlShader controlShader;
PEvaluationShader evalutionShader; PEvaluationShader evalutionShader;
@@ -128,7 +131,7 @@ public:
PGraphics graphics, PGraphics graphics,
RenderPassType passName, RenderPassType passName,
PMaterial material, PMaterial material,
PVertexShaderInput vertexInput, VertexInputType* vertexInput,
bool bPositionOnly); bool bPositionOnly);
private: private:
Array<ShaderCollection> shaders; Array<ShaderCollection> shaders;
@@ -272,7 +275,7 @@ struct QueueFamilyMapping
class QueueOwnedResource class QueueOwnedResource
{ {
public: public:
QueueOwnedResource(PGraphics graphics, QueueType startQueueType); QueueOwnedResource(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~QueueOwnedResource(); virtual ~QueueOwnedResource();
//Preliminary checks to see if the barrier should be executed at all //Preliminary checks to see if the barrier should be executed at all
@@ -281,14 +284,20 @@ public:
protected: protected:
virtual void executeOwnershipBarrier(QueueType newOwner) = 0; virtual void executeOwnershipBarrier(QueueType newOwner) = 0;
Gfx::QueueType currentOwner; Gfx::QueueType currentOwner;
PGraphics graphics; QueueFamilyMapping mapping;
}; };
DEFINE_REF(QueueOwnedResource); DEFINE_REF(QueueOwnedResource);
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Buffer : public QueueOwnedResource class Buffer : public QueueOwnedResource
{ {
public: public:
Buffer(PGraphics graphics, QueueType startQueueType); Buffer(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Buffer(); virtual ~Buffer();
protected: protected:
@@ -299,7 +308,7 @@ protected:
class UniformBuffer : public Buffer class UniformBuffer : public Buffer
{ {
public: public:
UniformBuffer(PGraphics graphics, QueueType startQueueType); UniformBuffer(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~UniformBuffer(); virtual ~UniformBuffer();
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
@@ -310,7 +319,7 @@ DEFINE_REF(UniformBuffer);
class VertexBuffer : public Buffer class VertexBuffer : public Buffer
{ {
public: public:
VertexBuffer(PGraphics graphics, uint32 numVertices, uint32 vertexSize, QueueType startQueueType); VertexBuffer(QueueFamilyMapping mapping, uint32 numVertices, uint32 vertexSize, QueueType startQueueType);
virtual ~VertexBuffer(); virtual ~VertexBuffer();
inline uint32 getNumVertices() inline uint32 getNumVertices()
{ {
@@ -333,7 +342,7 @@ DEFINE_REF(VertexBuffer);
class IndexBuffer : public Buffer class IndexBuffer : public Buffer
{ {
public: public:
IndexBuffer(PGraphics graphics, uint32 size, Gfx::SeIndexType index, QueueType startQueueType); IndexBuffer(QueueFamilyMapping mapping, uint32 size, Gfx::SeIndexType index, QueueType startQueueType);
virtual ~IndexBuffer(); virtual ~IndexBuffer();
inline uint32 getNumIndices() const inline uint32 getNumIndices() const
{ {
@@ -355,7 +364,7 @@ DEFINE_REF(IndexBuffer);
class StructuredBuffer : public Buffer class StructuredBuffer : public Buffer
{ {
public: public:
StructuredBuffer(PGraphics graphics, QueueType startQueueType); StructuredBuffer(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~StructuredBuffer(); virtual ~StructuredBuffer();
protected: protected:
// Inherited via QueueOwnedResource // Inherited via QueueOwnedResource
@@ -367,7 +376,7 @@ class VertexStream
{ {
public: public:
VertexStream(); VertexStream();
VertexStream(uint32 stride, uint32 offset, uint8 instanced, Gfx::PVertexBuffer vertexBuffer); VertexStream(uint32 stride, uint32 offset, uint8 instanced);
~VertexStream(); ~VertexStream();
void addVertexElement(VertexElement element); void addVertexElement(VertexElement element);
const Array<VertexElement> getVertexDescriptions() const; const Array<VertexElement> getVertexDescriptions() const;
@@ -377,7 +386,6 @@ public:
uint32 offset; uint32 offset;
Array<VertexElement> vertexDescription; Array<VertexElement> vertexDescription;
uint8 instanced; uint8 instanced;
PVertexBuffer vertexBuffer;
}; };
DEFINE_REF(VertexStream); DEFINE_REF(VertexStream);
class VertexDeclaration class VertexDeclaration
@@ -385,7 +393,7 @@ class VertexDeclaration
public: public:
VertexDeclaration(); VertexDeclaration();
~VertexDeclaration(); ~VertexDeclaration();
uint32 addVertexStream(const VertexStream &vertexStream); uint32 addVertexStream(const VertexStreamComponent &vertexStream);
const Array<VertexStream> &getVertexStreams() const; const Array<VertexStream> &getVertexStreams() const;
private: private:
@@ -404,10 +412,17 @@ protected:
GraphicsPipelineCreateInfo createInfo; GraphicsPipelineCreateInfo createInfo;
}; };
DEFINE_REF(GraphicsPipeline); DEFINE_REF(GraphicsPipeline);
// IMPORTANT!!
// WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE
// ALWAYS PUT THE Gfx:: BASE CLASS FIRST
// This is because the refcounting object is unique per allocation, so
// the base address of both the Gfx:: and the implementation class
// need to match for it to work
class Texture : public QueueOwnedResource class Texture : public QueueOwnedResource
{ {
public: public:
Texture(PGraphics graphics, QueueType startQueueType); Texture(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture(); virtual ~Texture();
virtual SeFormat getFormat() const = 0; virtual SeFormat getFormat() const = 0;
@@ -422,7 +437,7 @@ DEFINE_REF(Texture);
class Texture2D : public Texture class Texture2D : public Texture
{ {
public: public:
Texture2D(PGraphics graphics, QueueType startQueueType); Texture2D(QueueFamilyMapping mapping, QueueType startQueueType);
virtual ~Texture2D(); virtual ~Texture2D();
virtual SeFormat getFormat() const = 0; virtual SeFormat getFormat() const = 0;
+2 -2
View File
@@ -2,8 +2,8 @@
using namespace Seele; using namespace Seele;
Mesh::Mesh(MeshDescription description, Gfx::PIndexBuffer indexBuffer) Mesh::Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer)
: description(description) : vertexInput(vertexInput)
, indexBuffer(indexBuffer) , indexBuffer(indexBuffer)
{ {
} }
+4 -5
View File
@@ -4,7 +4,7 @@
namespace Seele namespace Seele
{ {
#define MAX_TEX_CHANNELS 8 /*#define MAX_TEX_CHANNELS 8
struct MeshDescription struct MeshDescription
{ {
Array<Gfx::VertexAttribute> layout; Array<Gfx::VertexAttribute> layout;
@@ -41,23 +41,22 @@ struct MeshDescription
ar & layout; ar & layout;
//TODO declaration //TODO declaration
} }
}; };*/
DECLARE_REF(MaterialAsset); DECLARE_REF(MaterialAsset);
class Mesh class Mesh
{ {
public: public:
Mesh(MeshDescription description, Gfx::PIndexBuffer indexBuffer); Mesh(PVertexShaderInput vertexInput, Gfx::PIndexBuffer indexBuffer);
~Mesh(); ~Mesh();
Gfx::PIndexBuffer indexBuffer; Gfx::PIndexBuffer indexBuffer;
MeshDescription description; PVertexShaderInput vertexInput;
PMaterialAsset referencedMaterial; PMaterialAsset referencedMaterial;
private: private:
friend class boost::serialization::access; friend class boost::serialization::access;
template<class Archive> template<class Archive>
void serialize(Archive& ar, const unsigned int version) void serialize(Archive& ar, const unsigned int version)
{ {
ar & description;
ar & referencedMaterial->getFullPath(); ar & referencedMaterial->getFullPath();
//TODO: //TODO:
} }
+1 -15
View File
@@ -12,21 +12,6 @@ Seele::RenderCore::~RenderCore()
void Seele::RenderCore::init() void Seele::RenderCore::init()
{ {
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280;
mainWindowInfo.height = 720;
mainWindowInfo.bFullscreen = false;
mainWindowInfo.numSamples = 1;
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_R8G8B8_UNORM;
auto window = windowManager->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 1280;
sceneViewInfo.sizeY = 720;
sceneViewInfo.offsetX = 0;
sceneViewInfo.offsetY = 0;
PSceneView sceneView = new SceneView(windowManager->getGraphics(), window, sceneViewInfo);
window->addView(sceneView);
} }
void Seele::RenderCore::renderLoop() void Seele::RenderCore::renderLoop()
@@ -34,6 +19,7 @@ void Seele::RenderCore::renderLoop()
while (windowManager->isActive()) while (windowManager->isActive())
{ {
windowManager->beginFrame(); windowManager->beginFrame();
windowManager->render();
windowManager->endFrame(); windowManager->endFrame();
} }
} }
+1
View File
@@ -12,6 +12,7 @@ public:
void renderLoop(); void renderLoop();
void shutdown(); void shutdown();
PWindowManager getWindowManager() const { return windowManager; };
private: private:
PScene scene; PScene scene;
PWindowManager windowManager; PWindowManager windowManager;
+4
View File
@@ -0,0 +1,4 @@
#include "RenderMaterial.h"
using namespace Seele;
using namespace Seele::Gfx;
+44
View File
@@ -0,0 +1,44 @@
#pragma once
#include "GraphicsResources.h"
namespace Seele
{
namespace Gfx
{
class MaterialShaderMap;//TODO implement
class MaterialRenderContext;
struct UniformExpressionCache
{
Gfx::PUniformBuffer uniformBuffer;
uint8 bUpToDate;
const MaterialShaderMap* cachedUniformExpressionShaderMap;
};
class Material;
class RenderMaterial
{
public:
mutable UniformExpressionCache uniformExpressionCache;
RenderMaterial();
virtual ~RenderMaterial();
void evaluateUniformExpressions(UniformExpressionCache& outUniforExpressionCache, const MaterialRenderContext& context);
void cacheUniformExpressions(bool bRecreatueUniformBuffer);
void invalidateUniformExpressionCache(bool bRecreateUniformBuffer);
void updateUniformExpressionCacheIfNeeded() const;
const Material* getMaterial() const
{
const RenderMaterial* unused = nullptr;
return &getMaterialWithFallback(unused);
}
virtual const Material& getMaterialWithFallback(const RenderMaterial*& outFallbackRenderMaterial) const = 0;
virtual Material* getMaterialNoFallback() const { return nullptr; }
};
} // namespace Gfx
} // namespace Seele
+4 -6
View File
@@ -27,7 +27,8 @@ void BasePassMeshProcessor::addMeshBatch(
//TODO query tesselation //TODO query tesselation
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput); const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
assert(collection != nullptr);
Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); Gfx::PRenderCommand renderCommand = graphics->createRenderCommand();
buildMeshDrawCommand(batch, buildMeshDrawCommand(batch,
primitiveComponent, primitiveComponent,
@@ -79,12 +80,9 @@ void BasePass::render()
{ {
processor->clearCommands(); processor->clearCommands();
graphics->beginRenderPass(renderPass); graphics->beginRenderPass(renderPass);
for (auto &&primitive : scene->getPrimitives()) for (auto &&primitive : scene->getStaticMeshes())
{ {
for (auto &&meshBatch : primitive->staticMeshes) processor->addMeshBatch(primitive, nullptr, renderPass);
{
processor->addMeshBatch(meshBatch, primitive, renderPass);
}
} }
graphics->executeCommands(processor->getRenderCommands()); graphics->executeCommands(processor->getRenderCommands());
graphics->endRenderPass(); graphics->endRenderPass();
+3 -6
View File
@@ -5,14 +5,11 @@
using namespace Seele; using namespace Seele;
SceneRenderPath::SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target) SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target)
: RenderPath(graphics, target) : RenderPath(graphics, target)
, basePass(new BasePass(scene, graphics, target)) , scene(scene)
{ {
scene = new Scene(); basePass = new BasePass(scene, graphics, target);
PMeshAsset asset = AssetRegistry::findMesh("Unbenannt");
PActor rootActor = new Actor();
PPrimitiveComponent primitiveComponent = new PrimitiveComponent();
} }
SceneRenderPath::~SceneRenderPath() SceneRenderPath::~SceneRenderPath()
+1 -1
View File
@@ -8,7 +8,7 @@ DECLARE_REF(Scene);
class SceneRenderPath : public RenderPath class SceneRenderPath : public RenderPath
{ {
public: public:
SceneRenderPath(Gfx::PGraphics graphics, Gfx::PViewport target); SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PViewport target);
virtual ~SceneRenderPath(); virtual ~SceneRenderPath();
void setTargetScene(PScene scene); void setTargetScene(PScene scene);
virtual void init(); virtual void init();
+2 -1
View File
@@ -8,7 +8,8 @@ using namespace Seele;
Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo) Seele::SceneView::SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo)
: View(graphics, owner, createInfo) : View(graphics, owner, createInfo)
{ {
renderer = new SceneRenderPath(graphics, viewport); scene = new Scene(graphics);
renderer = new SceneRenderPath(scene, graphics, viewport);
} }
Seele::SceneView::~SceneView() Seele::SceneView::~SceneView()
+4
View File
@@ -2,11 +2,15 @@
#include "View.h" #include "View.h"
namespace Seele namespace Seele
{ {
DECLARE_REF(Scene);
class SceneView : public View class SceneView : public View
{ {
public: public:
SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo); SceneView(Gfx::PGraphics graphics, PWindow owner, const ViewportCreateInfo &createInfo);
~SceneView(); ~SceneView();
PScene getScene() const { return scene; }
private:
PScene scene;
}; };
DEFINE_REF(SceneView); DEFINE_REF(SceneView);
} // namespace Seele } // namespace Seele
+27
View File
@@ -0,0 +1,27 @@
#include "ShaderCompiler.h"
#include "Material/Material.h"
#include "VertexShaderInput.h"
using namespace Seele;
using namespace Seele::Gfx;
ShaderCompiler::ShaderCompiler(PGraphics graphics)
: graphics(graphics)
{
}
ShaderCompiler::~ShaderCompiler()
{
}
void ShaderCompiler::registerMaterial(PMaterial material)
{
for(auto type : VertexInputType::getTypeList())
{
material->createShaders(graphics, Gfx::RenderPassType::DepthPrepass, type);
material->createShaders(graphics, Gfx::RenderPassType::BasePass, type);
}
}
+22
View File
@@ -0,0 +1,22 @@
#pragma once
#include "GraphicsResources.h"
namespace Seele
{
DECLARE_REF(Material);
DECLARE_NAME_REF(Gfx, Graphics);
namespace Gfx
{
class ShaderCompiler
{
public:
ShaderCompiler(PGraphics graphics);
~ShaderCompiler();
void registerMaterial(PMaterial material);
private:
Array<PMaterial> pendingCompiles;
PGraphics graphics;
};
DEFINE_REF(ShaderCompiler);
} // namespace Gfx
} // namespace Seele
@@ -0,0 +1,48 @@
#include "StaticMeshVertexInput.h"
using namespace Seele;
StaticMeshVertexInput::StaticMeshVertexInput(std::string name)
: VertexShaderInput(name)
{
}
StaticMeshVertexInput::~StaticMeshVertexInput()
{
}
void StaticMeshVertexInput::setPositionStream(const VertexStreamComponent& positionStream)
{
declaration->addVertexStream(positionStream);
positionDeclaration->addVertexStream(positionStream);
data.positionStream = positionStream;
}
void StaticMeshVertexInput::setTangentXStream(const VertexStreamComponent& tangentXStream)
{
declaration->addVertexStream(tangentXStream);
data.tangentBasisComponents[0] = tangentXStream;
}
void StaticMeshVertexInput::setTangentZStream(const VertexStreamComponent& tangentZStream)
{
declaration->addVertexStream(tangentZStream);
data.tangentBasisComponents[1] = tangentZStream;
}
void StaticMeshVertexInput::setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream)
{
//TODO: replace add with proper indexing
declaration->addVertexStream(textureStream);
data.textureCoordinates.add(textureStream);
}
void StaticMeshVertexInput::setColorStream(const VertexStreamComponent& colorStream)
{
declaration->addVertexStream(colorStream);
data.colorComponent = colorStream;
}
IMPLEMENT_VERTEX_INPUT_TYPE(StaticMeshVertexInput, "StaticMeshVertexInput");
@@ -0,0 +1,32 @@
#pragma once
#include "VertexShaderInput.h"
namespace Seele
{
enum { MAX_TEXCOORDS = 4 };
struct StaticMeshDataType
{
VertexStreamComponent positionStream;
VertexStreamComponent tangentBasisComponents[2];
//Dont forget these are 4 component vectors
Array<VertexStreamComponent> textureCoordinates;
VertexStreamComponent colorComponent;
};
class StaticMeshVertexInput : public VertexShaderInput
{
DECLARE_VERTEX_INPUT_TYPE(StaticMeshVertexInput);
public:
StaticMeshVertexInput(std::string name);
virtual ~StaticMeshVertexInput();
void setPositionStream(const VertexStreamComponent& positionStream);
void setTangentXStream(const VertexStreamComponent& tangentXStream);
void setTangentZStream(const VertexStreamComponent& tangentZStream);
void setTexCoordStream(uint32 index, const VertexStreamComponent& textureStream);
void setColorStream(const VertexStreamComponent& colorStream);
private:
StaticMeshDataType data;
};
DEFINE_REF(StaticMeshVertexInput);
}
+44 -29
View File
@@ -5,49 +5,64 @@
using namespace Seele; using namespace Seele;
List<PVertexShaderInput> VertexShaderInput::registeredInputs; List<VertexInputType*> VertexInputType::globalTypeList;
std::mutex VertexShaderInput::registeredInputsLock;
List<VertexInputType*> VertexInputType::getTypeList()
{
return globalTypeList;
}
VertexInputType* VertexInputType::getVertexInputByName(const std::string& name)
{
for(auto type : globalTypeList)
{
if(name.compare(type->getName()) == 0)
{
return type;
}
}
return nullptr;
}
VertexInputType::VertexInputType(const char* name,
const char* shaderFilename)
: name(name)
, shaderFilename(shaderFilename)
{
globalTypeList.add(this);
}
VertexInputType::~VertexInputType()
{
globalTypeList.remove(globalTypeList.find(this));
}
const char* VertexInputType::getName()
{
return name;
}
const char* VertexInputType::getShaderFilename()
{
return shaderFilename;
}
VertexShaderInput::VertexShaderInput(std::string name) VertexShaderInput::VertexShaderInput(std::string name)
: name(name) : name(name)
{ {
std::scoped_lock lock(registeredInputsLock); declaration = new Gfx::VertexDeclaration();
registeredInputs.add(this);
}
VertexShaderInput::VertexShaderInput(MeshDescription description, std::string name)
: declaration(description.declaration)
, layout(description.layout)
, name(name)
{
auto declStreams = declaration->getVertexStreams();
std::copy(declStreams.begin(), declStreams.end(), streams.begin());
uint32 positionStreamIndex = 0;
positionDeclaration = new Gfx::VertexDeclaration(); positionDeclaration = new Gfx::VertexDeclaration();
for (uint32 i = 0; i < declStreams.size(); i++)
{
if(description.layout[i] == Gfx::VertexAttribute::POSITION)
{
positionStreams[positionStreamIndex++] = declStreams[i];
positionDeclaration->addVertexStream(declStreams[i]);
}
}
std::scoped_lock lock(registeredInputsLock);
registeredInputs.add(this);
} }
VertexShaderInput::~VertexShaderInput() VertexShaderInput::~VertexShaderInput()
{ {
registeredInputs.remove(registeredInputs.find(this));
} }
void VertexShaderInput::getStreams(VertexInputStreamArray& outVertexStreams) const void VertexShaderInput::getStreams(VertexInputStreamArray& outVertexStreams) const
{ {
for(uint32 i = 0; i < streams.size(); ++i) for(uint32 i = 0; i < streams.size(); ++i)
{ {
const Gfx::VertexStream& stream = streams[i]; const VertexInputStream& stream = streams[i];
if(stream.vertexBuffer == nullptr) if(stream.vertexBuffer == nullptr)
{ {
outVertexStreams.add(VertexInputStream(i, 0, nullptr)); outVertexStreams.add(VertexInputStream(i, 0, nullptr));
@@ -63,7 +78,7 @@ void VertexShaderInput::getPositionOnlyStream(VertexInputStreamArray& outVertexS
{ {
for (uint32 i = 0; i < positionStreams.size(); ++i) for (uint32 i = 0; i < positionStreams.size(); ++i)
{ {
const Gfx::VertexStream& stream = positionStreams[i]; const VertexInputStream& stream = positionStreams[i];
outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer)); outVertexStreams.add(VertexInputStream(i, stream.offset, stream.vertexBuffer));
} }
} }
+79 -8
View File
@@ -5,6 +5,7 @@
namespace Seele namespace Seele
{ {
// Minimal vertex source used for building commands
struct VertexInputStream struct VertexInputStream
{ {
uint32 streamIndex : 4; uint32 streamIndex : 4;
@@ -35,33 +36,103 @@ struct VertexInputStream
return !(*this == rhs); return !(*this == rhs);
} }
}; };
typedef Array<VertexInputStream> VertexInputStreamArray; //TODO inline allocation
// Typed data source for a vertex factory
struct VertexStreamComponent
{
// Source vertex buffer
Gfx::PVertexBuffer vertexBuffer = nullptr;
// Offset to the start of the vertex buffer fetch
uint32 streamOffset = 0;
// Offset of the data, relative to the beginnning of each element in the vertex buffer
uint32 offset = 0;
// Stride of the data
uint32 stride = 0;
Gfx::SeFormat type = Gfx::SE_FORMAT_UNDEFINED;
VertexStreamComponent()
{}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(0)
, offset(offset)
, stride(stride)
, type(type)
{}
VertexStreamComponent(const Gfx::PVertexBuffer vertexBuffer, uint32 streamOffset, uint32 offset, uint32 stride, Gfx::SeFormat type)
: vertexBuffer(vertexBuffer)
, streamOffset(streamOffset)
, offset(offset)
, stride(stride)
, type(type)
{}
};
#define STRUCTMEMBER_VERTEXSTREAMCOMPONENT(vertexBuffer, vertexType, member, memberType) \
VertexStreamComponent(vertexBuffer, offsetof(vertexType, member), sizeof(vertexType), memberType)
class VertexInputType
{
public:
static List<VertexInputType*> getTypeList();
static VertexInputType* getVertexInputByName(const std::string& name);
VertexInputType(
const char* name,
const char* shaderFilename
);
virtual ~VertexInputType();
const char* getName();
const char* getShaderFilename();
private:
const char* name;
const char* shaderFilename;
static List<VertexInputType*> globalTypeList;
};
#define DECLARE_VERTEX_INPUT_TYPE(inputClass) \
public: \
static VertexInputType staticType; \
virtual VertexInputType* getType() const override;
#define IMPLEMENT_VERTEX_INPUT_TYPE(inputClass, shaderFilename) \
VertexInputType inputClass::staticType( \
#inputClass, \
shaderFilename); \
VertexInputType* inputClass::getType() const { return &staticType; }
typedef Array<VertexInputStream> VertexInputStreamArray;
struct MeshDescription; struct MeshDescription;
DECLARE_REF(VertexShaderInput); DECLARE_REF(VertexShaderInput);
class VertexShaderInput class VertexShaderInput
{ {
public: public:
VertexShaderInput(std::string name); VertexShaderInput(std::string name);
VertexShaderInput(MeshDescription description, std::string name); virtual ~VertexShaderInput();
~VertexShaderInput();
void getStreams(VertexInputStreamArray& outVertexStreams) const; void getStreams(VertexInputStreamArray& outVertexStreams) const;
void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const; void getPositionOnlyStream(VertexInputStreamArray& outVertexStreams) const;
virtual bool supportsTesselation() { return false; } virtual bool supportsTesselation() { return false; }
virtual VertexInputType* getType() const { return nullptr; }
Gfx::PVertexDeclaration getDeclaration() const {return declaration;} Gfx::PVertexDeclaration getDeclaration() const {return declaration;}
Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;} Gfx::PVertexDeclaration getPositionDeclaration() const {return positionDeclaration;}
std::string getName() const { return name; } std::string getName() const { return name; }
std::string getCode() const { return code; } protected:
private:
static List<PVertexShaderInput> registeredInputs; static List<PVertexShaderInput> registeredInputs;
static std::mutex registeredInputsLock; static std::mutex registeredInputsLock;
Array<Gfx::VertexAttribute> layout; Array<Gfx::VertexAttribute> layout;
StaticArray<Gfx::VertexStream, 16> streams; StaticArray<VertexInputStream, 16> streams;
StaticArray<Gfx::VertexStream, 16> positionStreams; StaticArray<VertexInputStream, 16> positionStreams;
Gfx::PVertexDeclaration declaration; Gfx::PVertexDeclaration declaration;
Gfx::PVertexDeclaration positionDeclaration; Gfx::PVertexDeclaration positionDeclaration;
std::string name; std::string name;
std::string code;
}; };
DEFINE_REF(VertexShaderInput); DEFINE_REF(VertexShaderInput);
} // namespace Seele } // namespace Seele
@@ -114,7 +114,7 @@ PSubAllocation Allocation::getSuballocation(VkDeviceSize requestedSize, VkDevice
void Allocation::markFree(SubAllocation *allocation) void Allocation::markFree(SubAllocation *allocation)
{ {
// Dont free if it is already a free allocation, since they also mark themselves on deletion // Dont free if it is already a free allocation, since they also mark themselves on deletion
if(freeRanges.find(allocation->allocatedOffset) != nullptr) if (freeRanges.find(allocation->allocatedOffset) != nullptr)
{ {
return; return;
} }
@@ -286,6 +286,8 @@ void StagingManager::clearPending()
PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead) PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageFlags usage, bool bCPURead)
{ {
std::unique_lock l(lock);
for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it) for (auto it = freeBuffers.begin(); it != freeBuffers.end(); ++it)
{ {
auto freeBuffer = *it; auto freeBuffer = *it;
@@ -296,6 +298,7 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
return freeBuffer; return freeBuffer;
} }
} }
PStagingBuffer stagingBuffer = new StagingBuffer(); PStagingBuffer stagingBuffer = new StagingBuffer();
VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size); VkBufferCreateInfo stagingBufferCreateInfo = init::BufferCreateInfo(usage, size);
VkDevice vulkanDevice = graphics->getDevice(); VkDevice vulkanDevice = graphics->getDevice();
@@ -322,11 +325,13 @@ PStagingBuffer StagingManager::allocateStagingBuffer(uint32 size, VkBufferUsageF
vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset()); vkBindBufferMemory(graphics->getDevice(), stagingBuffer->buffer, stagingBuffer->getMemoryHandle(), stagingBuffer->getOffset());
activeBuffers.add(stagingBuffer.getHandle()); activeBuffers.add(stagingBuffer.getHandle());
return stagingBuffer; return stagingBuffer;
} }
void StagingManager::releaseStagingBuffer(PStagingBuffer buffer) void StagingManager::releaseStagingBuffer(PStagingBuffer buffer)
{ {
std::unique_lock l(lock);
freeBuffers.add(buffer); freeBuffers.add(buffer);
activeBuffers.remove(activeBuffers.find(buffer.getHandle())); activeBuffers.remove(activeBuffers.find(buffer.getHandle()));
} }
@@ -213,6 +213,7 @@ private:
PAllocator allocator; PAllocator allocator;
Array<PStagingBuffer> freeBuffers; Array<PStagingBuffer> freeBuffers;
Array<StagingBuffer *> activeBuffers; Array<StagingBuffer *> activeBuffers;
std::mutex lock;
}; };
DEFINE_REF(StagingManager); DEFINE_REF(StagingManager);
} // namespace Vulkan } // namespace Vulkan
+22 -21
View File
@@ -14,9 +14,9 @@ struct PendingBuffer
bool bWriteOnly; bool bWriteOnly;
}; };
static Map<Buffer *, PendingBuffer> pendingBuffers; static Map<ShaderBuffer *, PendingBuffer> pendingBuffers;
Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType) ShaderBuffer::ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType)
: graphics(graphics), currentBuffer(0), size(size), currentOwner(queueType) : graphics(graphics), currentBuffer(0), size(size), currentOwner(queueType)
{ {
if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT || if (usage & VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT ||
@@ -56,21 +56,22 @@ Buffer::Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::Q
info.sharingMode = VK_SHARING_MODE_EXCLUSIVE; info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
} }
Buffer::~Buffer() ShaderBuffer::~ShaderBuffer()
{ {
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence(); auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
auto &deletionQueue = graphics->getDeletionQueue(); auto &deletionQueue = graphics->getDeletionQueue();
VkDevice device = graphics->getDevice(); VkDevice device = graphics->getDevice();
VkBuffer buf[Gfx::numFramesBuffered]; VkBuffer buf[Gfx::numFramesBuffered];
for (uint32 i = 0; i < numBuffers; ++i) for (uint32 i = 0; i < numBuffers; ++i)
{ {
buf[i] = buffers[i].buffer; buf[i] = buffers[i].buffer;
deletionQueue.addPendingDelete(fence, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); }); deletionQueue.addPendingDelete(cmdBuffer, [device, buf, i]() { vkDestroyBuffer(device, buf[i], nullptr); });
buffers[i].allocation = nullptr; buffers[i].allocation = nullptr;
} }
graphics = nullptr;
} }
void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void ShaderBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
VkBufferMemoryBarrier barrier = VkBufferMemoryBarrier barrier =
init::BufferMemoryBarrier(); init::BufferMemoryBarrier();
@@ -137,7 +138,7 @@ void Buffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
currentOwner = newOwner; currentOwner = newOwner;
} }
void *Buffer::lock(bool bWriteOnly) void *ShaderBuffer::lock(bool bWriteOnly)
{ {
void *data = nullptr; void *data = nullptr;
@@ -208,7 +209,7 @@ void *Buffer::lock(bool bWriteOnly)
return data; return data;
} }
void Buffer::unlock() void ShaderBuffer::unlock()
{ {
auto found = pendingBuffers.find(this); auto found = pendingBuffers.find(this);
if (found != pendingBuffers.end()) if (found != pendingBuffers.end())
@@ -233,8 +234,8 @@ void Buffer::unlock()
} }
UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData) UniformBuffer::UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner) : Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, resourceData.owner)
, Gfx::UniformBuffer(graphics, resourceData.owner) , Gfx::UniformBuffer(graphics->getFamilyMapping(), resourceData.owner)
{ {
if (resourceData.data != nullptr) if (resourceData.data != nullptr)
{ {
@@ -251,12 +252,12 @@ UniformBuffer::~UniformBuffer()
void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner) void UniformBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
{ {
Gfx::QueueOwnedResource::transferOwnership(newOwner); Gfx::QueueOwnedResource::transferOwnership(newOwner);
Buffer::currentOwner = newOwner; Vulkan::ShaderBuffer::currentOwner = newOwner;
} }
void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void UniformBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
Buffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
VkAccessFlags UniformBuffer::getSourceAccessMask() VkAccessFlags UniformBuffer::getSourceAccessMask()
@@ -270,8 +271,8 @@ VkAccessFlags UniformBuffer::getDestAccessMask()
} }
StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData) StructuredBuffer::StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData)
: Buffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner) : Vulkan::ShaderBuffer(graphics, resourceData.size, VK_BUFFER_USAGE_STORAGE_BUFFER_BIT, resourceData.owner)
, Gfx::StructuredBuffer(graphics, resourceData.owner) , Gfx::StructuredBuffer(graphics->getFamilyMapping(), resourceData.owner)
{ {
if (resourceData.data != nullptr) if (resourceData.data != nullptr)
{ {
@@ -292,7 +293,7 @@ void StructuredBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void StructuredBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
Buffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
VkAccessFlags StructuredBuffer::getSourceAccessMask() VkAccessFlags StructuredBuffer::getSourceAccessMask()
@@ -306,8 +307,8 @@ VkAccessFlags StructuredBuffer::getDestAccessMask()
} }
VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData) VertexBuffer::VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData)
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner) : Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_VERTEX_BUFFER_BIT, resourceData.resourceData.owner)
, Gfx::VertexBuffer(graphics, resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner) , Gfx::VertexBuffer(graphics->getFamilyMapping(), resourceData.numVertices, resourceData.vertexSize, resourceData.resourceData.owner)
{ {
if (resourceData.resourceData.data != nullptr) if (resourceData.resourceData.data != nullptr)
{ {
@@ -328,7 +329,7 @@ void VertexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void VertexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
Buffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
VkAccessFlags VertexBuffer::getSourceAccessMask() VkAccessFlags VertexBuffer::getSourceAccessMask()
@@ -342,8 +343,8 @@ VkAccessFlags VertexBuffer::getDestAccessMask()
} }
IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData) IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData)
: Buffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner) : Vulkan::ShaderBuffer(graphics, resourceData.resourceData.size, VK_BUFFER_USAGE_INDEX_BUFFER_BIT, resourceData.resourceData.owner)
, Gfx::IndexBuffer(graphics, resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner) , Gfx::IndexBuffer(graphics->getFamilyMapping(), resourceData.resourceData.size, resourceData.indexType, resourceData.resourceData.owner)
{ {
if (resourceData.resourceData.data != nullptr) if (resourceData.resourceData.data != nullptr)
{ {
@@ -364,7 +365,7 @@ void IndexBuffer::requestOwnershipTransfer(Gfx::QueueType newOwner)
void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner) void IndexBuffer::executeOwnershipBarrier(Gfx::QueueType newOwner)
{ {
Buffer::executeOwnershipBarrier(newOwner); Vulkan::ShaderBuffer::executeOwnershipBarrier(newOwner);
} }
VkAccessFlags IndexBuffer::getSourceAccessMask() VkAccessFlags IndexBuffer::getSourceAccessMask()
@@ -22,8 +22,8 @@ CmdBufferBase::~CmdBufferBase()
graphics = nullptr; graphics = nullptr;
} }
CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool) CmdBuffer::CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager)
: CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0) : CmdBufferBase(graphics, cmdPool), renderPass(nullptr), framebuffer(nullptr), subpassIndex(0), manager(manager)
{ {
VkCommandBufferAllocateInfo allocInfo = VkCommandBufferAllocateInfo allocInfo =
init::CommandBufferAllocateInfo(cmdPool, init::CommandBufferAllocateInfo(cmdPool,
@@ -120,6 +120,11 @@ PFence CmdBuffer::getFence()
return fence; return fence;
} }
PCommandBufferManager CmdBuffer::getManager()
{
return manager;
}
SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool) SecondaryCmdBuffer::SecondaryCmdBuffer(PGraphics graphics, VkCommandPool cmdPool)
: CmdBufferBase(graphics, cmdPool) : CmdBufferBase(graphics, cmdPool)
{ {
@@ -195,8 +200,9 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool)); VK_CHECK(vkCreateCommandPool(graphics->getDevice(), &info, nullptr, &commandPool));
activeCmdBuffer = new CmdBuffer(graphics, commandPool); activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
activeCmdBuffer->begin(); activeCmdBuffer->begin();
std::lock_guard lock(allocatedBufferLock);
allocatedBuffers.add(activeCmdBuffer); allocatedBuffers.add(activeCmdBuffer);
} }
@@ -236,6 +242,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
queue->submitCommandBuffer(activeCmdBuffer); queue->submitCommandBuffer(activeCmdBuffer);
} }
} }
std::lock_guard lock(allocatedBufferLock);
for (uint32 i = 0; i < allocatedBuffers.size(); ++i) for (uint32 i = 0; i < allocatedBuffers.size(); ++i)
{ {
PCmdBuffer cmdBuffer = allocatedBuffers[i]; PCmdBuffer cmdBuffer = allocatedBuffers[i];
@@ -251,7 +258,7 @@ void CommandBufferManager::submitCommands(PSemaphore signalSemaphore)
assert(cmdBuffer->state == CmdBuffer::State::Submitted); assert(cmdBuffer->state == CmdBuffer::State::Submitted);
} }
} }
activeCmdBuffer = new CmdBuffer(graphics, commandPool); activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
allocatedBuffers.add(activeCmdBuffer); allocatedBuffers.add(activeCmdBuffer);
activeCmdBuffer->begin(); activeCmdBuffer->begin();
} }
@@ -30,10 +30,11 @@ protected:
DEFINE_REF(CmdBufferBase); DEFINE_REF(CmdBufferBase);
DECLARE_REF(SecondaryCmdBuffer); DECLARE_REF(SecondaryCmdBuffer);
DECLARE_REF(CommandBufferManager);
class CmdBuffer : public CmdBufferBase class CmdBuffer : public CmdBufferBase
{ {
public: public:
CmdBuffer(PGraphics graphics, VkCommandPool cmdPool); CmdBuffer(PGraphics graphics, VkCommandPool cmdPool, PCommandBufferManager manager);
virtual ~CmdBuffer(); virtual ~CmdBuffer();
void begin(); void begin();
void end(); void end();
@@ -43,6 +44,7 @@ public:
void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore); void addWaitSemaphore(VkPipelineStageFlags stages, PSemaphore waitSemaphore);
void refreshFence(); void refreshFence();
PFence getFence(); PFence getFence();
PCommandBufferManager getManager();
enum State enum State
{ {
ReadyBegin, ReadyBegin,
@@ -53,6 +55,7 @@ public:
}; };
private: private:
PCommandBufferManager manager;
PRenderPass renderPass; PRenderPass renderPass;
PFramebuffer framebuffer; PFramebuffer framebuffer;
PFence fence; PFence fence;
@@ -105,6 +108,7 @@ private:
PQueue queue; PQueue queue;
uint32 queueFamilyIndex; uint32 queueFamilyIndex;
PCmdBuffer activeCmdBuffer; PCmdBuffer activeCmdBuffer;
std::mutex allocatedBufferLock;
Array<PCmdBuffer> allocatedBuffers; Array<PCmdBuffer> allocatedBuffers;
}; };
DEFINE_REF(CommandBufferManager); DEFINE_REF(CommandBufferManager);
@@ -49,4 +49,5 @@ Framebuffer::Framebuffer(PGraphics graphics, PRenderPass renderPass, Gfx::PRende
Framebuffer::~Framebuffer() Framebuffer::~Framebuffer()
{ {
vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr); vkDestroyFramebuffer(graphics->getDevice(), handle, nullptr);
graphics = nullptr;
} }
@@ -64,6 +64,7 @@ void Graphics::beginRenderPass(Gfx::PRenderPass renderPass)
if (found == allocatedFramebuffers.end()) if (found == allocatedFramebuffers.end())
{ {
framebuffer = new Framebuffer(this, rp, rp->getLayout()); framebuffer = new Framebuffer(this, rp, rp->getLayout());
allocatedFramebuffers[framebufferHash] = framebuffer;
} }
else else
{ {
@@ -23,10 +23,10 @@ QueueOwnedResourceDeletion::~QueueOwnedResourceDeletion()
worker.join(); worker.join();
} }
void QueueOwnedResourceDeletion::addPendingDelete(PFence fence, std::function<void()> func) void QueueOwnedResourceDeletion::addPendingDelete(PCmdBuffer cmdbuffer, std::function<void()> func)
{ {
PendingItem item; PendingItem item;
item.fence = fence; item.cmdBuffer = cmdbuffer;
item.func = func; item.func = func;
deletionQueue.add(item); deletionQueue.add(item);
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
@@ -40,13 +40,12 @@ void QueueOwnedResourceDeletion::run()
std::unique_lock<std::mutex> lock(mutex); std::unique_lock<std::mutex> lock(mutex);
cv.wait(lock); cv.wait(lock);
auto entry = deletionQueue.begin(); auto entry = deletionQueue.begin();
PFence fence = entry->fence; PCmdBuffer cmdBuffer = entry->cmdBuffer;
fence->wait(1000ull); //cmdBuffer->getManager()->waitForCommands(cmdBuffer);
if (fence->isSignaled()) //cmdBuffer->begin();
{
entry->func(); //entry->func();
deletionQueue.remove(entry); deletionQueue.remove(entry);
}
} }
} }
@@ -10,6 +10,7 @@ namespace Vulkan
DECLARE_REF(DescriptorAllocator); DECLARE_REF(DescriptorAllocator);
DECLARE_REF(CommandBufferManager); DECLARE_REF(CommandBufferManager);
DECLARE_REF(CmdBuffer);
DECLARE_REF(Graphics); DECLARE_REF(Graphics);
DECLARE_REF(SubAllocation); DECLARE_REF(SubAllocation);
class Semaphore class Semaphore
@@ -57,7 +58,7 @@ class QueueOwnedResourceDeletion
public: public:
QueueOwnedResourceDeletion(); QueueOwnedResourceDeletion();
virtual ~QueueOwnedResourceDeletion(); virtual ~QueueOwnedResourceDeletion();
static void addPendingDelete(PFence fence, std::function<void()> function); static void addPendingDelete(PCmdBuffer fence, std::function<void()> function);
private: private:
std::thread worker; std::thread worker;
@@ -65,7 +66,7 @@ private:
static void run(); static void run();
struct PendingItem struct PendingItem
{ {
PFence fence; PCmdBuffer cmdBuffer;
std::function<void()> func; std::function<void()> func;
}; };
static std::mutex mutex; static std::mutex mutex;
@@ -73,11 +74,11 @@ private:
static List<PendingItem> deletionQueue; static List<PendingItem> deletionQueue;
}; };
class Buffer class ShaderBuffer
{ {
public: public:
Buffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType); ShaderBuffer(PGraphics graphics, uint32 size, VkBufferUsageFlags usage, Gfx::QueueType queueType);
virtual ~Buffer(); virtual ~ShaderBuffer();
VkBuffer getHandle() const VkBuffer getHandle() const
{ {
return buffers[currentBuffer].buffer; return buffers[currentBuffer].buffer;
@@ -108,9 +109,9 @@ protected:
virtual VkAccessFlags getSourceAccessMask() = 0; virtual VkAccessFlags getSourceAccessMask() = 0;
virtual VkAccessFlags getDestAccessMask() = 0; virtual VkAccessFlags getDestAccessMask() = 0;
}; };
DEFINE_REF(Buffer); DEFINE_REF(ShaderBuffer);
class UniformBuffer : public Buffer, public Gfx::UniformBuffer class UniformBuffer : public Gfx::UniformBuffer, public ShaderBuffer
{ {
public: public:
UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData); UniformBuffer(PGraphics graphics, const BulkResourceData &resourceData);
@@ -126,7 +127,7 @@ protected:
}; };
DEFINE_REF(UniformBuffer); DEFINE_REF(UniformBuffer);
class StructuredBuffer : public Buffer, public Gfx::StructuredBuffer class StructuredBuffer : public Gfx::StructuredBuffer, public ShaderBuffer
{ {
public: public:
StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData); StructuredBuffer(PGraphics graphics, const BulkResourceData &resourceData);
@@ -142,7 +143,7 @@ protected:
}; };
DEFINE_REF(StructuredBuffer); DEFINE_REF(StructuredBuffer);
class VertexBuffer : public Buffer, public Gfx::VertexBuffer class VertexBuffer : public Gfx::VertexBuffer, public ShaderBuffer
{ {
public: public:
VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData); VertexBuffer(PGraphics graphics, const VertexBufferCreateInfo &resourceData);
@@ -158,7 +159,7 @@ protected:
}; };
DEFINE_REF(VertexBuffer); DEFINE_REF(VertexBuffer);
class IndexBuffer : public Buffer, public Gfx::IndexBuffer class IndexBuffer : public Gfx::IndexBuffer, public ShaderBuffer
{ {
public: public:
IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData); IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo &resourceData);
@@ -249,7 +250,7 @@ protected:
}; };
DEFINE_REF(TextureBase); DEFINE_REF(TextureBase);
class Texture2D : public TextureBase, public Gfx::Texture2D class Texture2D : public Gfx::Texture2D, public TextureBase
{ {
public: public:
Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE); Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage = VK_NULL_HANDLE);
@@ -242,7 +242,6 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo
0 0
); );
createInfo.pStages = stageInfos; createInfo.pStages = stageInfos;
createInfo.pVertexInputState = &vertexInput; createInfo.pVertexInputState = &vertexInput;
createInfo.pInputAssemblyState = &assemblyInfo; createInfo.pInputAssemblyState = &assemblyInfo;
+7 -3
View File
@@ -55,7 +55,6 @@ void Shader::create(const ShaderCreateInfo& createInfo)
int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV); int targetIndex = spAddCodeGenTarget(request, SLANG_SPIRV);
spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk")); spSetTargetProfile(request, targetIndex, spFindProfile(session, "glsl_vk"));
spSetDumpIntermediates(request, true); spSetDumpIntermediates(request, true);
int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, ""); int translationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "");
for(auto code : createInfo.shaderCode) for(auto code : createInfo.shaderCode)
@@ -67,15 +66,20 @@ void Shader::create(const ShaderCreateInfo& createInfo)
code.data() code.data()
); );
} }
for(auto define : createInfo.defines)
{
spAddPreprocessorDefine(request, define.key, define.value);
}
spAddSearchPath(request, "shaders/lib/"); spAddSearchPath(request, "shaders/lib/");
spAddSearchPath(request, "shaders/generated/");
spSetGlobalGenericArgs(request, createInfo.typeParameter.size(), createInfo.typeParameter.data()); spSetGlobalGenericArgs(request, createInfo.typeParameter.size(), createInfo.typeParameter.data());
int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type)); int entryPointIndex = spAddEntryPoint(request, translationUnitIndex, entryPointName.c_str(), getStageFromShaderType(type));
if(spCompile(request)) if(spCompile(request))
{ {
char const* diagnostice = spGetDiagnosticOutput(request); char const* diagnostics = spGetDiagnosticOutput(request);
std::cout << diagnostice << std::endl; std::cout << diagnostics << std::endl;
} }
ShaderReflection* reflection = slang::ShaderReflection::get(request); ShaderReflection* reflection = slang::ShaderReflection::get(request);
+4 -4
View File
@@ -154,12 +154,12 @@ TextureHandle::TextureHandle(PGraphics graphics, VkImageViewType viewType,
TextureHandle::~TextureHandle() TextureHandle::~TextureHandle()
{ {
auto &deletionQueue = graphics->getDeletionQueue(); auto &deletionQueue = graphics->getDeletionQueue();
auto fence = graphics->getQueueCommands(currentOwner)->getCommands()->getFence(); auto cmdBuffer = graphics->getQueueCommands(currentOwner)->getCommands();
VkDevice device = graphics->getDevice(); VkDevice device = graphics->getDevice();
VkImageView view = defaultView; VkImageView view = defaultView;
VkImage img = image; VkImage img = image;
deletionQueue.addPendingDelete(fence, [device, view]() { vkDestroyImageView(device, view, nullptr); }); deletionQueue.addPendingDelete(cmdBuffer, [device, view]() { vkDestroyImageView(device, view, nullptr); });
deletionQueue.addPendingDelete(fence, [device, img]() { vkDestroyImage(device, img, nullptr); }); deletionQueue.addPendingDelete(cmdBuffer, [device, img]() { vkDestroyImage(device, img, nullptr); });
} }
void TextureHandle::changeLayout(VkImageLayout newLayout) void TextureHandle::changeLayout(VkImageLayout newLayout)
@@ -243,7 +243,7 @@ void TextureBase::changeLayout(VkImageLayout newLayout)
} }
Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage) Texture2D::Texture2D(PGraphics graphics, const TextureCreateInfo& createInfo, VkImage existingImage)
: Gfx::Texture2D(graphics, createInfo.resourceData.owner) : Gfx::Texture2D(graphics->getFamilyMapping(), createInfo.resourceData.owner)
{ {
textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D, textureHandle = new TextureHandle(graphics, createInfo.bArray ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D,
createInfo, existingImage); createInfo, existingImage);
+8
View File
@@ -42,6 +42,14 @@ void Seele::WindowManager::beginFrame()
} }
} }
void WindowManager::render()
{
for(auto window : windows)
{
window->render();
}
}
void Seele::WindowManager::endFrame() void Seele::WindowManager::endFrame()
{ {
for (auto window : windows) for (auto window : windows)
+1
View File
@@ -13,6 +13,7 @@ public:
~WindowManager(); ~WindowManager();
PWindow addWindow(const WindowCreateInfo &createInfo); PWindow addWindow(const WindowCreateInfo &createInfo);
void beginFrame(); void beginFrame();
void render();
void endFrame(); void endFrame();
static Gfx::PGraphics getGraphics() static Gfx::PGraphics getGraphics()
{ {
+132
View File
@@ -0,0 +1,132 @@
#include "BRDF.h"
#include <sstream>
#include <fstream>
#include <nlohmann/json.hpp>
using namespace Seele;
using json = nlohmann::json;
List<BRDF*> BRDF::globalBRDFList;
BRDF::BRDF(const char* name)
: name(name)
{
globalBRDFList.add(this);
}
BRDF::~BRDF()
{
globalBRDFList.remove(globalBRDFList.find(this));
}
BRDF* BRDF::getBRDFByName(const std::string& name)
{
for(auto brdf : globalBRDFList)
{
if(name.compare(brdf->name) == 0)
{
return brdf;
}
}
return nullptr;
}
List<BRDF*> BRDF::getBRDFList()
{
return globalBRDFList;
}
BlinnPhong::BlinnPhong(const char* name)
: BRDF(name)
{
}
BlinnPhong::~BlinnPhong()
{
}
void BlinnPhong::generateMaterialCode(std::ofstream& codeStream, json codeJson)
{
std::stringstream accessorStream;
auto generateAccessor = [codeJson](std::stringstream& accessorStream, const std::string& key, const std::string& defaultVal)
{
if(codeJson.contains(key))
{
for(auto code : codeJson[key].items())
{
accessorStream << code.value().get<std::string>() << ";" << std::endl;
}
}
else
{
accessorStream << "return " << defaultVal << ";";
}
};
accessorStream << "float3 getBaseColor(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "baseColor", "float3(0, 0, 0)");
accessorStream << "}";
accessorStream << "float getMetallic(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "metallic", "0.f");
accessorStream << "}";
accessorStream << "float3 getNormal(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "normal", "float3(0, 1, 0)");
accessorStream << "}";
accessorStream << "float getSpecular(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "specular", "0.f");
accessorStream << "}";
accessorStream << "float getRoughness(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "roughness", "0.f");
accessorStream << "}";
accessorStream << "float getSheen(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "sheen", "0.f");
accessorStream << "}";
/*accessorStream << "float getSpecularTint(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "specularTint", "0.f");
accessorStream << "}";
accessorStream << "float getAnisotropic(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "anisotropic", "0.f");
accessorStream << "}";
accessorStream << "float getSheenTint(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "sheenTint", "0.f");
accessorStream << "}";
accessorStream << "float getClearCoat(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "clearCoat", "0.f");
accessorStream << "}";
accessorStream << "float getClearCoatGloss(MaterialFragmentParameter input) {\n";
generateAccessor(accessorStream, "clearCoatGloss", "0.f");
accessorStream << "}";*/
accessorStream << "float3 getWorldOffset() {\n";
generateAccessor(accessorStream, "worldOffset", "0.f");
accessorStream << "}";
codeStream << accessorStream.str();
codeStream << "typedef " << name << " BRDF;" << std::endl;
codeStream << name << " prepare(MaterialFragmentParameter geometry){" << std::endl;
codeStream << name << " result;" << std::endl;
codeStream << "result.baseColor = getBaseColor(geometry);" << std::endl;
codeStream << "result.metallic = getMetallic(geometry);" << std::endl;
codeStream << "result.normal = geometry.transformNormalTexture(getNormal(geometry));" << std::endl;
codeStream << "result.specular = getSpecular(geometry);" << std::endl;
codeStream << "result.roughness = getRoughness(geometry);" << std::endl;
codeStream << "result.sheen = getSheen(geometry);" << std::endl;
codeStream << "return result;" << std::endl;
codeStream << "}" << std::endl;
}
IMPLEMENT_BRDF(BlinnPhong);
+39
View File
@@ -0,0 +1,39 @@
#pragma once
#include "MinimalEngine.h"
#include "Containers/List.h"
#include <nlohmann/json_fwd.hpp>
namespace Seele
{
class BRDF
{
public:
static BRDF* getBRDFByName(const std::string& name);
static List<BRDF*> getBRDFList();
virtual void generateMaterialCode(std::ofstream& codeStream, nlohmann::json codeJson) = 0;
protected:
BRDF(const char* name);
virtual ~BRDF();
static List<BRDF*> globalBRDFList;
const char* name;
};
#define DECLARE_BRDF(inputClass) \
public: \
static inputClass staticType;
#define IMPLEMENT_BRDF(inputClass) \
inputClass inputClass::staticType( \
#inputClass);
class BlinnPhong : public BRDF
{
DECLARE_BRDF(BlinnPhong);
public:
virtual void generateMaterialCode(std::ofstream& codeStream, nlohmann::json codeJson);
protected:
BlinnPhong(const char* name);
virtual ~BlinnPhong();
};
} // namespace Seele
+2
View File
@@ -1,5 +1,7 @@
target_sources(SeeleEngine target_sources(SeeleEngine
PRIVATE PRIVATE
BRDF.h
BRDF.cpp
Material.h Material.h
Material.cpp Material.cpp
MaterialAsset.h MaterialAsset.h
+17 -16
View File
@@ -1,6 +1,7 @@
#include "Material.h" #include "Material.h"
#include "Asset/AssetRegistry.h" #include "Asset/AssetRegistry.h"
#include "Graphics/VertexShaderInput.h" #include "Graphics/VertexShaderInput.h"
#include "BRDF.h"
#include <nlohmann/json.hpp> #include <nlohmann/json.hpp>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
@@ -45,13 +46,15 @@ void Material::compile()
auto& stream = getReadStream(); auto& stream = getReadStream();
json j; json j;
stream >> j; stream >> j;
std::stringstream codeStream;
materialName = j["name"].get<std::string>(); materialName = j["name"].get<std::string>();
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
std::string profile = j["profile"].get<std::string>(); std::string profile = j["profile"].get<std::string>();
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
codeStream << "import LightEnv;" << std::endl; codeStream << "import LightEnv;" << std::endl;
codeStream << "import Material;" << std::endl; codeStream << "import Material;" << std::endl;
codeStream << "import BRDF;" << std::endl; codeStream << "import BRDF;" << std::endl;
codeStream << "import InputGeometry;" << std::endl; codeStream << "import MaterialParameter;" << std::endl;
codeStream << "struct " << materialName << ": IMaterial {" << std::endl; codeStream << "struct " << materialName << ": IMaterial {" << std::endl;
for(auto param : j["params"].items()) for(auto param : j["params"].items())
@@ -62,6 +65,7 @@ void Material::compile()
if(type.compare("float") == 0) if(type.compare("float") == 0)
{ {
PFloatParameter p = new FloatParameter(); PFloatParameter p = new FloatParameter();
p->name = param.key();
if(default != param.value().end()) if(default != param.value().end())
{ {
p->defaultValue = std::stof(default.value().get<std::string>()); p->defaultValue = std::stof(default.value().get<std::string>());
@@ -71,6 +75,7 @@ void Material::compile()
else if(type.compare("float3") == 0) else if(type.compare("float3") == 0)
{ {
PVectorParameter p = new VectorParameter(); PVectorParameter p = new VectorParameter();
p->name = param.key();
if(default != param.value().end()) if(default != param.value().end())
{ {
p->defaultValue = parseVector(default.value().get<std::string>().c_str()); p->defaultValue = parseVector(default.value().get<std::string>().c_str());
@@ -80,6 +85,7 @@ void Material::compile()
else if(type.compare("Texture2D") == 0) else if(type.compare("Texture2D") == 0)
{ {
PTextureParameter p = new TextureParameter(); PTextureParameter p = new TextureParameter();
p->name = param.key();
if(default != param.value().end()) if(default != param.value().end())
{ {
@@ -89,37 +95,32 @@ void Material::compile()
else if(type.compare("SamplerState") == 0) else if(type.compare("SamplerState") == 0)
{ {
PSamplerParameter p = new SamplerParameter(); PSamplerParameter p = new SamplerParameter();
p->name = param.key();
parameters.add(p); parameters.add(p);
} }
else else
{ {
std::cout << "Error unsupported parameter type" << std::endl; std::cout << "Error unsupported parameter type" << std::endl;
} }
codeStream << type << " " << param.key(); codeStream << type << " " << param.key() << ";\n";
} }
codeStream << "typedef " << profile << " BRDF;" << std::endl; BRDF* brdf = BRDF::getBRDFByName(profile);
codeStream << profile << " prepare(MaterialPixelParameter geometry){" << std::endl; brdf->generateMaterialCode(codeStream, j["code"]);
codeStream << profile << " result;" << std::endl; codeStream << "};";
for(auto c : j["code"].items()) codeStream.close();
{
codeStream << c.value().get<std::string>() << std::endl;
}
codeStream << "}};" << std::endl;
materialCode = codeStream.str();
} }
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, PVertexShaderInput vertexInput) const const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
{ {
Gfx::ShaderPermutation permutation; Gfx::ShaderPermutation permutation;
std::string materialName = getMaterialName(); std::string materialName = getFileName();
std::string vertexInputName = vertexInput->getName(); std::string vertexInputName = vertexInput->getName();
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
std::memcpy(permutation.materialName, vertexInputName.c_str(), sizeof(permutation.materialName)); std::memcpy(permutation.materialName, vertexInputName.c_str(), sizeof(permutation.materialName));
return shaderMap.findShaders(Gfx::PermutationId(permutation)); return shaderMap.findShaders(Gfx::PermutationId(permutation));
} }
Gfx::ShaderCollection& Material::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, PVertexShaderInput vertexInput) Gfx::ShaderCollection& Material::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
{ {
std::lock_guard lock(shaderMapLock); std::lock_guard lock(shaderMapLock);
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false); return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
+6 -7
View File
@@ -4,7 +4,7 @@
namespace Seele namespace Seele
{ {
class VertexInputType;
class Material : public MaterialAsset class Material : public MaterialAsset
{ {
public: public:
@@ -14,18 +14,17 @@ public:
~Material(); ~Material();
virtual void save() override; virtual void save() override;
virtual void load() override; virtual void load() override;
virtual std::string getMaterialName() const { return materialName; } virtual PMaterial getRenderMaterial() { return this; }
inline std::string getCode() const { return materialCode; } const std::string& getName() {return materialName;}
const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, PVertexShaderInput vertexInput) const; const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, PVertexShaderInput vertexInput); Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
void compile();
private: private:
static Gfx::ShaderMap shaderMap; static Gfx::ShaderMap shaderMap;
static std::mutex shaderMapLock; static std::mutex shaderMapLock;
void compile();
std::string materialName; std::string materialName;
std::string materialCode;
friend class MaterialLoader; friend class MaterialLoader;
}; };
DEFINE_REF(Material); DEFINE_REF(Material);
+2 -1
View File
@@ -6,6 +6,7 @@
namespace Seele namespace Seele
{ {
DECLARE_REF(VertexShaderInput); DECLARE_REF(VertexShaderInput);
DECLARE_REF(Material);
class MaterialAsset : public Asset class MaterialAsset : public Asset
{ {
public: public:
@@ -15,7 +16,7 @@ public:
~MaterialAsset(); ~MaterialAsset();
virtual void save() = 0; virtual void save() = 0;
virtual void load() = 0; virtual void load() = 0;
virtual std::string getMaterialName() const = 0; virtual PMaterial getRenderMaterial() = 0;
Gfx::SeBlendOp getBlendMode() const {return Gfx::SE_BLEND_OP_END_RANGE;} Gfx::SeBlendOp getBlendMode() const {return Gfx::SE_BLEND_OP_END_RANGE;}
Gfx::MaterialShadingModel getShadingModel() const {return Gfx::MaterialShadingModel::DefaultLit;} Gfx::MaterialShadingModel getShadingModel() const {return Gfx::MaterialShadingModel::DefaultLit;}
+2 -2
View File
@@ -31,9 +31,9 @@ void MaterialInstance::load()
} }
inline std::string MaterialInstance::getMaterialName() const PMaterial MaterialInstance::getRenderMaterial()
{ {
return baseMaterial->getMaterialName(); return baseMaterial;
} }
PMaterial MaterialInstance::getBaseMaterial() const PMaterial MaterialInstance::getBaseMaterial() const
+1 -1
View File
@@ -14,7 +14,7 @@ public:
~MaterialInstance(); ~MaterialInstance();
virtual void save() override; virtual void save() override;
virtual void load() override; virtual void load() override;
inline std::string getMaterialName() const; virtual PMaterial getRenderMaterial();
PMaterial getBaseMaterial() const; PMaterial getBaseMaterial() const;
Gfx::PDescriptorSet getDescriptor(); Gfx::PDescriptorSet getDescriptor();
private: private:
+7 -2
View File
@@ -48,7 +48,10 @@ public:
} }
~RefObject() ~RefObject()
{ {
registeredObjects.erase(handle); {
std::scoped_lock lock(registeredObjectsLock);
registeredObjects.erase(handle);
}
// we cant always have the definition of every class // we cant always have the definition of every class
#pragma warning(disable : 4150) #pragma warning(disable : 4150)
delete handle; delete handle;
@@ -122,7 +125,9 @@ public:
} }
RefPtr(T *ptr) RefPtr(T *ptr)
{ {
std::unique_lock l(registeredObjectsLock);
auto registeredObj = registeredObjects.find(ptr); auto registeredObj = registeredObjects.find(ptr);
l.unlock();
if (registeredObj == registeredObjects.end()) if (registeredObj == registeredObjects.end())
{ {
object = new RefObject<T>(ptr); object = new RefObject<T>(ptr);
@@ -155,7 +160,7 @@ public:
RefPtr(const RefPtr<F> &other) RefPtr(const RefPtr<F> &other)
{ {
F *f = other.getObject()->getHandle(); F *f = other.getObject()->getHandle();
static_cast<T *>(f); T* t = static_cast<T *>(f);
object = (RefObject<T> *)other.getObject(); object = (RefObject<T> *)other.getObject();
object->addRef(); object->addRef();
} }
@@ -12,6 +12,29 @@ PrimitiveComponent::PrimitiveComponent()
PrimitiveComponent::PrimitiveComponent(PMeshAsset asset) PrimitiveComponent::PrimitiveComponent(PMeshAsset asset)
{ {
auto assetMeshes = asset->getMeshes();
staticMeshes.resize(assetMeshes.size());
for (uint32 i = 0; i < assetMeshes.size(); i++)
{
auto& batch = staticMeshes[i];
batch.material = assetMeshes[i]->referencedMaterial->getRenderMaterial();
batch.isBackfaceCullingDisabled = false;
batch.isCastingShadow = true;
batch.primitiveComponent = this;
batch.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST;
batch.useReverseCulling = false;
batch.useWireframe = false;
batch.vertexInput = assetMeshes[i]->vertexInput;
auto& batchElement = batch.elements.add();
batchElement.baseVertexIndex = 0;
batchElement.firstIndex = 0;
batchElement.indexBuffer = assetMeshes[i]->indexBuffer;
batchElement.indirectArgsBuffer = nullptr;
batchElement.instanceRuns = nullptr;
batchElement.isInstanced = false;
batchElement.numInstances = 1;
batchElement.numPrimitives = assetMeshes[i]->indexBuffer->getNumIndices() / 3; //TODO: hardcoded
}
} }
PrimitiveComponent::~PrimitiveComponent() PrimitiveComponent::~PrimitiveComponent()
@@ -6,7 +6,7 @@ namespace Seele
struct PrimitiveUniformBuffer struct PrimitiveUniformBuffer
{ {
Matrix4 localToWorld; Matrix4 localToWorld;
Vector4 worldToLocal; Matrix4 worldToLocal;
Vector4 actorWorldPosition; Vector4 actorWorldPosition;
}; };
} // namespace Seele } // namespace Seele
+21 -1
View File
@@ -1,11 +1,14 @@
#include "Scene.h" #include "Scene.h"
#include "Components/PrimitiveComponent.h" #include "Components/PrimitiveComponent.h"
#include "Components/PrimitiveUniformBufferLayout.h"
#include "Material/MaterialInstance.h" #include "Material/MaterialInstance.h"
#include "Material/Material.h" #include "Material/Material.h"
#include "Graphics/Graphics.h"
using namespace Seele; using namespace Seele;
Scene::Scene() Scene::Scene(Gfx::PGraphics graphics)
: graphics(graphics)
{ {
} }
@@ -30,4 +33,21 @@ void Scene::addActor(PActor actor)
void Scene::addPrimitiveComponent(PPrimitiveComponent comp) void Scene::addPrimitiveComponent(PPrimitiveComponent comp)
{ {
primitives.add(comp); primitives.add(comp);
for(auto batch : comp->staticMeshes)
{
PrimitiveUniformBuffer data;
data.actorWorldPosition = Vector4(comp->getTransform().getPosition(), 1);
data.localToWorld = comp->getRenderMatrix();
data.worldToLocal = glm::inverse(data.localToWorld);
BulkResourceData createInfo;
createInfo.data = reinterpret_cast<uint8*>(&data);
createInfo.owner = Gfx::QueueType::GRAPHICS;
createInfo.size = sizeof(data);
Gfx::PUniformBuffer uniformBuffer = graphics->createUniformBuffer(createInfo);
for(auto& element : batch.elements)
{
element.uniformBuffer = uniformBuffer;
}
staticMeshes.add(batch);
}
} }
+4 -3
View File
@@ -13,17 +13,18 @@ DECLARE_REF(Material);
class Scene class Scene
{ {
public: public:
Scene(); Scene(Gfx::PGraphics graphics);
~Scene(); ~Scene();
void tick(float deltaTime); void tick(float deltaTime);
void addActor(PActor actor); void addActor(PActor actor);
void addPrimitiveComponent(PPrimitiveComponent comp); void addPrimitiveComponent(PPrimitiveComponent comp);
const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; } const Array<PPrimitiveComponent>& getPrimitives() const { return primitives; }
const Array<MeshBatch>& getStaticMeshes() const { return staticMeshes; }
private: private:
Array<MeshBatch> meshBatches; Array<MeshBatch> staticMeshes;
Array<PActor> rootActors; Array<PActor> rootActors;
Array<PPrimitiveComponent> primitives; Array<PPrimitiveComponent> primitives;
public: Gfx::PGraphics graphics;
}; };
} // namespace Seele } // namespace Seele
+18
View File
@@ -1,12 +1,30 @@
#include "Graphics/RenderCore.h" #include "Graphics/RenderCore.h"
#include "Graphics/SceneView.h"
#include "Asset/AssetRegistry.h" #include "Asset/AssetRegistry.h"
using namespace Seele; using namespace Seele;
int main() int main()
{ {
RenderCore core; RenderCore core;
core.init(); core.init();
WindowCreateInfo mainWindowInfo;
mainWindowInfo.title = "SeeleEngine";
mainWindowInfo.width = 1280;
mainWindowInfo.height = 720;
mainWindowInfo.bFullscreen = false;
mainWindowInfo.numSamples = 1;
mainWindowInfo.pixelFormat = Gfx::SE_FORMAT_R8G8B8_UNORM;
auto window = core.getWindowManager()->addWindow(mainWindowInfo);
ViewportCreateInfo sceneViewInfo;
sceneViewInfo.sizeX = 1280;
sceneViewInfo.sizeY = 720;
sceneViewInfo.offsetX = 0;
sceneViewInfo.offsetY = 0;
PSceneView sceneView = new SceneView(core.getWindowManager()->getGraphics(), window, sceneViewInfo);
window->addView(sceneView);
AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject"); AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject");
AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Arissa\\Arissa.fbx"); AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Arissa\\Arissa.fbx");
PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Arissa"));
sceneView->getScene()->addPrimitiveComponent(arissa);
core.renderLoop(); core.renderLoop();
core.shutdown(); core.shutdown();
return 0; return 0;