Improving Material shader code generation

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