Improving Material shader code generation
This commit is contained in:
Vendored
+13
-1
@@ -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,
|
||||||
|
|||||||
Vendored
+1
-1
Submodule external/slang updated: dd980b492a...bc0d0f9e2a
@@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
@@ -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;"
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+7
-1
@@ -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;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
|
|||||||
@@ -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,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;
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,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,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:
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#include "RenderMaterial.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
using namespace Seele::Gfx;
|
||||||
@@ -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
|
||||||
@@ -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();
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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);
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user