Finished writeup and fixed crashes
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
#include "TextureLoader.h"
|
||||
#include "MaterialLoader.h"
|
||||
#include "MeshLoader.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "MeshAsset.h"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "MaterialLoader.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "AssetRegistry.h"
|
||||
|
||||
using namespace Seele;
|
||||
@@ -8,8 +8,8 @@ using namespace Seele;
|
||||
MaterialLoader::MaterialLoader(Gfx::PGraphics graphics)
|
||||
: graphics(graphics)
|
||||
{
|
||||
placeholderMaterial = new Material(std::filesystem::absolute("./shaders/Placeholder.asset"));
|
||||
placeholderMaterial->compile();
|
||||
placeholderMaterial = new MaterialAsset(std::filesystem::absolute("./shaders/Placeholder.asset"));
|
||||
placeholderMaterial->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(placeholderMaterial);
|
||||
}
|
||||
|
||||
@@ -17,10 +17,10 @@ MaterialLoader::~MaterialLoader()
|
||||
{
|
||||
}
|
||||
|
||||
PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath)
|
||||
PMaterialAsset MaterialLoader::queueAsset(const std::filesystem::path& filePath)
|
||||
{
|
||||
PMaterial result = new Material(filePath);
|
||||
result->compile();
|
||||
PMaterialAsset result = new MaterialAsset(filePath);
|
||||
result->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(result);
|
||||
AssetRegistry::get().registerMaterial(result);
|
||||
// TODO: There is actually no real reason to import a standalone material,
|
||||
@@ -28,7 +28,7 @@ PMaterial MaterialLoader::queueAsset(const std::filesystem::path& filePath)
|
||||
return result;
|
||||
}
|
||||
|
||||
PMaterial MaterialLoader::getPlaceHolderMaterial()
|
||||
PMaterialAsset MaterialLoader::getPlaceHolderMaterial()
|
||||
{
|
||||
return placeholderMaterial;
|
||||
}
|
||||
|
||||
@@ -7,19 +7,19 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material)
|
||||
DECLARE_REF(MaterialAsset)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
class MaterialLoader
|
||||
{
|
||||
public:
|
||||
MaterialLoader(Gfx::PGraphics graphic);
|
||||
~MaterialLoader();
|
||||
PMaterial queueAsset(const std::filesystem::path& filePath);
|
||||
PMaterial getPlaceHolderMaterial();
|
||||
PMaterialAsset queueAsset(const std::filesystem::path& filePath);
|
||||
PMaterialAsset getPlaceHolderMaterial();
|
||||
private:
|
||||
Gfx::PGraphics graphics;
|
||||
List<std::future<void>> futures;
|
||||
PMaterial placeholderMaterial;
|
||||
PMaterialAsset placeholderMaterial;
|
||||
};
|
||||
DEFINE_REF(MaterialLoader)
|
||||
} // namespace Seele
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/StaticMeshVertexInput.h"
|
||||
#include "AssetRegistry.h"
|
||||
#include "Material/Material.h"
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
@@ -88,8 +87,8 @@ void MeshLoader::loadMaterials(const aiScene* scene, Array<PMaterialAsset>& glob
|
||||
outMatFile.close();
|
||||
|
||||
std::cout << "writing json to " << outMatFilename << std::endl;
|
||||
PMaterial result = new Material(outMatFilename);
|
||||
result->compile();
|
||||
PMaterialAsset result = new MaterialAsset(outMatFilename);
|
||||
result->load();
|
||||
graphics->getShaderCompiler()->registerMaterial(result);
|
||||
AssetRegistry::get().registerMaterial(result);
|
||||
PMaterialAsset asset = AssetRegistry::findMaterial(result->getFileName());
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
#include "GraphicsResources.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Graphics.h"
|
||||
#include "RenderPass/DepthPrepass.h"
|
||||
#include "RenderPass/BasePass.h"
|
||||
@@ -55,7 +53,7 @@ const ShaderCollection* ShaderMap::findShaders(PermutationId&& id) const
|
||||
ShaderCollection& ShaderMap::createShaders(
|
||||
PGraphics graphics,
|
||||
RenderPassType renderPass,
|
||||
PMaterial material,
|
||||
PMaterialAsset material,
|
||||
VertexInputType* vertexInput,
|
||||
bool /*bPositionOnly*/)
|
||||
{
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Seele
|
||||
struct VertexInputStream;
|
||||
struct VertexStreamComponent;
|
||||
class VertexInputType;
|
||||
DECLARE_REF(Material)
|
||||
namespace Gfx
|
||||
{
|
||||
DECLARE_REF(Graphics)
|
||||
@@ -140,7 +139,7 @@ public:
|
||||
ShaderCollection& createShaders(
|
||||
PGraphics graphics,
|
||||
RenderPassType passName,
|
||||
PMaterial material,
|
||||
PMaterialAsset material,
|
||||
VertexInputType* vertexInput,
|
||||
bool bPositionOnly);
|
||||
private:
|
||||
|
||||
@@ -34,7 +34,7 @@ void BasePassMeshProcessor::addMeshBatch(
|
||||
|
||||
const PVertexShaderInput vertexInput = batch.vertexInput;
|
||||
|
||||
const Gfx::ShaderCollection* collection = material->getRenderMaterial()->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
|
||||
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::BasePass, vertexInput->getType());
|
||||
assert(collection != nullptr);
|
||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||
{
|
||||
@@ -47,7 +47,7 @@ void BasePassMeshProcessor::addMeshBatch(
|
||||
renderCommand->setViewport(target);
|
||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||
{
|
||||
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout());
|
||||
pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getDescriptorLayout());
|
||||
pipelineLayout->create();
|
||||
descriptorSets[BasePass::INDEX_MATERIAL] = material->getDescriptor();
|
||||
descriptorSets[BasePass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++];
|
||||
|
||||
@@ -33,7 +33,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
|
||||
|
||||
const PVertexShaderInput vertexInput = batch.vertexInput;
|
||||
|
||||
const Gfx::ShaderCollection* collection = material->getRenderMaterial()->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
|
||||
const Gfx::ShaderCollection* collection = material->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType());
|
||||
assert(collection != nullptr);
|
||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||
{
|
||||
@@ -46,7 +46,7 @@ void DepthPrepassMeshProcessor::addMeshBatch(
|
||||
renderCommand->setViewport(target);
|
||||
for(uint32 i = 0; i < batch.elements.size(); ++i)
|
||||
{
|
||||
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout());
|
||||
pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getDescriptorLayout());
|
||||
pipelineLayout->create();
|
||||
descriptorSets[DepthPrepass::INDEX_MATERIAL] = material->getDescriptor();
|
||||
descriptorSets[DepthPrepass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++];
|
||||
|
||||
@@ -33,14 +33,19 @@ void LightCullingPass::beginFrame()
|
||||
uniformUpdate.data = (uint8*)&viewParams;
|
||||
viewParamsBuffer->updateContents(uniformUpdate);
|
||||
|
||||
LightEnv lightEnv = passData.lightEnv;
|
||||
for(uint32 i = 0; i < lightEnv.numPointLights; ++i)
|
||||
{
|
||||
lightEnv.pointLights[i].positionVS = lightEnv.pointLights[i].positionWS;
|
||||
}
|
||||
const LightEnv& lightEnv = passData.lightEnv;
|
||||
uniformUpdate.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.directionalLights;
|
||||
directLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
uniformUpdate.data = (uint8*)&lightEnv.pointLights;
|
||||
pointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
uniformUpdate.size = sizeof(uint32);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numDirectionalLights;
|
||||
numDirLightBuffer->updateContents(uniformUpdate);
|
||||
uniformUpdate.data = (uint8*)&lightEnv.numPointLights;
|
||||
numPointLightBuffer->updateContents(uniformUpdate);
|
||||
|
||||
BulkResourceData counterReset;
|
||||
uint32 reset = 0;
|
||||
@@ -64,6 +69,7 @@ void LightCullingPass::beginFrame()
|
||||
cullingDescriptorSet->updateTexture(8, oLightGrid);
|
||||
cullingDescriptorSet->updateTexture(9, tLightGrid);
|
||||
|
||||
|
||||
lightEnvDescriptorSet->updateBuffer(0, directLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(1, numDirLightBuffer);
|
||||
lightEnvDescriptorSet->updateBuffer(2, pointLightBuffer);
|
||||
@@ -133,30 +139,28 @@ void LightCullingPass::publishOutputs()
|
||||
resources->registerBufferOutput("LIGHTCULLING_OLIGHTLIST", oLightIndexList);
|
||||
resources->registerBufferOutput("LIGHTCULLING_TLIGHTLIST", tLightIndexList);
|
||||
|
||||
const LightEnv& lightEnv = passData.lightEnv;
|
||||
resourceData.size = sizeof(DirectionalLight) * MAX_DIRECTIONAL_LIGHTS;
|
||||
resourceData.data = (uint8*)&lightEnv.directionalLights;
|
||||
structInfo.resourceData = resourceData;
|
||||
structInfo.bDynamic = true;
|
||||
directLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
resourceData.size = sizeof(PointLight) * MAX_POINT_LIGHTS;
|
||||
resourceData.data = (uint8*)&lightEnv.pointLights;
|
||||
structInfo.resourceData = resourceData;
|
||||
pointLightBuffer = graphics->createStructuredBuffer(structInfo);
|
||||
|
||||
UniformBufferCreateInfo uniformInfo;
|
||||
resourceData.size = sizeof(uint32);
|
||||
resourceData.data = (uint8*)&lightEnv.numDirectionalLights;
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numDirLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
resourceData.data = (uint8*)&lightEnv.numPointLights;
|
||||
uniformInfo.resourceData = resourceData;
|
||||
uniformInfo.bDynamic = true;
|
||||
numPointLightBuffer = graphics->createUniformBuffer(uniformInfo);
|
||||
|
||||
resources->registerBufferOutput("DIRECTIONAL_LIGHTS", directLightBuffer);
|
||||
resources->registerUniformOutput("NUM_DIRECTIONAL_LIGHTS", numDirLightBuffer);
|
||||
resources->registerBufferOutput("POINT_LIGHTS", pointLightBuffer);
|
||||
resources->registerUniformOutput("NUM_POINT_LIGHTS", numPointLightBuffer);
|
||||
|
||||
TextureCreateInfo textureInfo;
|
||||
textureInfo.width = dispatchParams.numThreadGroups.x;
|
||||
textureInfo.height = dispatchParams.numThreadGroups.y;
|
||||
@@ -164,6 +168,7 @@ void LightCullingPass::publishOutputs()
|
||||
textureInfo.usage = Gfx::SE_IMAGE_USAGE_STORAGE_BIT;
|
||||
oLightGrid = graphics->createTexture2D(textureInfo);
|
||||
tLightGrid = graphics->createTexture2D(textureInfo);
|
||||
|
||||
resources->registerTextureOutput("LIGHTCULLING_OLIGHTGRID", oLightGrid);
|
||||
resources->registerTextureOutput("LIGHTCULLING_TLIGHTGRID", tLightGrid);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "ShaderCompiler.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "VertexShaderInput.h"
|
||||
|
||||
using namespace Seele;
|
||||
@@ -16,7 +16,7 @@ ShaderCompiler::~ShaderCompiler()
|
||||
|
||||
}
|
||||
|
||||
void ShaderCompiler::registerMaterial(PMaterial material)
|
||||
void ShaderCompiler::registerMaterial(PMaterialAsset material)
|
||||
{
|
||||
for(auto& type : VertexInputType::getTypeList())
|
||||
{
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(Material)
|
||||
DECLARE_NAME_REF(Gfx, Graphics)
|
||||
namespace Gfx
|
||||
{
|
||||
@@ -12,9 +11,9 @@ class ShaderCompiler
|
||||
public:
|
||||
ShaderCompiler(PGraphics graphics);
|
||||
~ShaderCompiler();
|
||||
void registerMaterial(PMaterial material);
|
||||
void registerMaterial(PMaterialAsset material);
|
||||
private:
|
||||
Array<PMaterial> pendingCompiles;
|
||||
Array<PMaterialAsset> pendingCompiles;
|
||||
PGraphics graphics;
|
||||
};
|
||||
DEFINE_REF(ShaderCompiler)
|
||||
|
||||
@@ -77,7 +77,7 @@ void GpuCrashTracker::Initialize()
|
||||
void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuCrashDumpSize)
|
||||
{
|
||||
// Make sure only one thread at a time...
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
// Write to file for later in-depth analysis with Nsight Graphics.
|
||||
WriteGpuCrashDumpToFile(pGpuCrashDump, gpuCrashDumpSize);
|
||||
@@ -87,7 +87,7 @@ void GpuCrashTracker::OnCrashDump(const void* pGpuCrashDump, const uint32_t gpuC
|
||||
void GpuCrashTracker::OnShaderDebugInfo(const void* pShaderDebugInfo, const uint32_t shaderDebugInfoSize)
|
||||
{
|
||||
// Make sure only one thread at a time...
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
std::unique_lock<std::mutex> lock(m_mutex);
|
||||
|
||||
// Get shader debug information identifier
|
||||
GFSDK_Aftermath_ShaderDebugInfoIdentifier identifier = {};
|
||||
|
||||
@@ -336,7 +336,7 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptorSet)
|
||||
auto descriptor = descriptorSet.cast<DescriptorSet>();
|
||||
boundDescriptors.add(descriptor.getHandle());
|
||||
descriptor->bind();
|
||||
//std::cout << "Binding descriptor " << descriptor->getHandle() << " to cmd " << handle << std::endl;
|
||||
|
||||
VkDescriptorSet setHandle = descriptor->getHandle();
|
||||
vkCmdBindDescriptorSets(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline->getLayout(), descriptorSet->getSetIndex(), 1, &setHandle, 0, nullptr);
|
||||
}
|
||||
@@ -373,7 +373,7 @@ CommandBufferManager::CommandBufferManager(PGraphics graphics, PQueue queue)
|
||||
|
||||
activeCmdBuffer = new CmdBuffer(graphics, commandPool, this);
|
||||
activeCmdBuffer->begin();
|
||||
std::lock_guard lock(allocatedBufferLock);
|
||||
std::unique_lock lock(allocatedBufferLock);
|
||||
allocatedBuffers.add(activeCmdBuffer);
|
||||
}
|
||||
|
||||
@@ -397,6 +397,7 @@ PRenderCommand CommandBufferManager::createRenderCommand(const std::string& name
|
||||
PRenderCommand cmdBuffer = allocatedRenderCommands[i];
|
||||
if (cmdBuffer->isReady())
|
||||
{
|
||||
cmdBuffer->name = name;
|
||||
cmdBuffer->begin(activeCmdBuffer);
|
||||
return cmdBuffer;
|
||||
}
|
||||
@@ -416,6 +417,7 @@ PComputeCommand CommandBufferManager::createComputeCommand(const std::string& na
|
||||
PComputeCommand cmdBuffer = allocatedComputeCommands[i];
|
||||
if (cmdBuffer->isReady())
|
||||
{
|
||||
cmdBuffer->name = name;
|
||||
cmdBuffer->begin(activeCmdBuffer);
|
||||
return cmdBuffer;
|
||||
}
|
||||
|
||||
@@ -2,11 +2,7 @@ target_sources(SeeleEngine
|
||||
PRIVATE
|
||||
BRDF.h
|
||||
BRDF.cpp
|
||||
Material.h
|
||||
Material.cpp
|
||||
MaterialAsset.h
|
||||
MaterialAsset.cpp
|
||||
MaterialInstance.h
|
||||
MaterialInstance.cpp
|
||||
ShaderExpression.h
|
||||
ShaderExpression.cpp)
|
||||
@@ -1,162 +0,0 @@
|
||||
#include "Material.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Graphics/VertexShaderInput.h"
|
||||
#include "BRDF.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Gfx::ShaderMap Material::shaderMap;
|
||||
std::mutex Material::shaderMapLock;
|
||||
|
||||
using namespace Seele;
|
||||
using json = nlohmann::json;
|
||||
|
||||
Material::Material()
|
||||
{
|
||||
}
|
||||
|
||||
Material::Material(const std::string& directory, const std::string& name)
|
||||
: MaterialAsset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
Material::Material(const std::filesystem::path& fullPath)
|
||||
: MaterialAsset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
Material::~Material()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::save()
|
||||
{
|
||||
}
|
||||
|
||||
void Material::load()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void Material::compile()
|
||||
{
|
||||
setStatus(Status::Loading);
|
||||
auto& stream = getReadStream();
|
||||
json j;
|
||||
stream >> j;
|
||||
materialName = j["name"].get<std::string>();
|
||||
layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout");
|
||||
//Shader file needs to conform to the slang standard, which prohibits _
|
||||
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
|
||||
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
|
||||
std::string profile = j["profile"].get<std::string>();
|
||||
|
||||
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
|
||||
codeStream << "import Material;" << std::endl;
|
||||
codeStream << "import BRDF;" << std::endl;
|
||||
codeStream << "import MaterialParameter;" << std::endl << std::endl;
|
||||
|
||||
codeStream << "struct " << materialName << " : IMaterial {" << std::endl;
|
||||
uint32 uniformBufferOffset = 0;
|
||||
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
|
||||
uniformBinding = -1;
|
||||
for(auto param : j["params"].items())
|
||||
{
|
||||
std::string type = param.value()["type"].get<std::string>();
|
||||
auto defaultValue = param.value().find("default");
|
||||
if(type.compare("float") == 0)
|
||||
{
|
||||
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 4;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = std::stof(defaultValue.value().get<std::string>());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("float3") == 0)
|
||||
{
|
||||
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 12;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("Texture2D") == 0)
|
||||
{
|
||||
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
std::string defaultString = defaultValue.value().get<std::string>();
|
||||
p->data = AssetRegistry::findTexture(defaultString);
|
||||
}
|
||||
else
|
||||
{
|
||||
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
|
||||
}
|
||||
assert(p->data != nullptr);
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("SamplerState") == 0)
|
||||
{
|
||||
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
||||
SamplerCreateInfo createInfo;
|
||||
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
|
||||
parameters.add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error unsupported parameter type" << std::endl;
|
||||
}
|
||||
codeStream << "\t" << type << " " << param.key() << ";\n";
|
||||
}
|
||||
uniformDataSize = uniformBufferOffset;
|
||||
if(uniformDataSize != 0)
|
||||
{
|
||||
uniformData = new uint8[uniformDataSize];
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
uniformInitializer.resourceData.data = uniformData;
|
||||
uniformInitializer.resourceData.size = uniformDataSize;
|
||||
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
|
||||
}
|
||||
BRDF* brdf = BRDF::getBRDFByName(profile);
|
||||
brdf->generateMaterialCode(codeStream, j["code"]);
|
||||
codeStream << "};";
|
||||
codeStream.close();
|
||||
layout->create();
|
||||
setStatus(Status::Ready);
|
||||
}
|
||||
|
||||
const Gfx::ShaderCollection* Material::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
|
||||
{
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.passType = renderPass;
|
||||
std::string vertexInputName = vertexInput->getName();
|
||||
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
|
||||
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
|
||||
return shaderMap.findShaders(Gfx::PermutationId(permutation));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "MaterialAsset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
class VertexInputType;
|
||||
class Material : public MaterialAsset
|
||||
{
|
||||
public:
|
||||
Material();
|
||||
Material(const std::string &directory, const std::string &name);
|
||||
Material(const std::filesystem::path& fullPath);
|
||||
~Material();
|
||||
virtual void save() override;
|
||||
virtual void load() override;
|
||||
virtual const Material* getRenderMaterial() const { return this; }
|
||||
Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
|
||||
// The name of the generated material shader, opposed to the name of the .asset file
|
||||
const std::string& getName() {return materialName;}
|
||||
|
||||
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;
|
||||
|
||||
std::string materialName;
|
||||
friend class MaterialLoader;
|
||||
friend class MaterialInstance;
|
||||
};
|
||||
DEFINE_REF(Material)
|
||||
} // namespace Seele
|
||||
@@ -1,5 +1,16 @@
|
||||
#include "MaterialAsset.h"
|
||||
#include "Window/WindowManager.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "BRDF.h"
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
|
||||
Gfx::ShaderMap MaterialAsset::shaderMap;
|
||||
std::mutex MaterialAsset::shaderMapLock;
|
||||
|
||||
using namespace Seele;
|
||||
using json = nlohmann::json;
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -21,6 +32,118 @@ MaterialAsset::~MaterialAsset()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void MaterialAsset::save()
|
||||
{
|
||||
assert(false && "TODO");
|
||||
}
|
||||
|
||||
void MaterialAsset::load()
|
||||
{
|
||||
setStatus(Status::Loading);
|
||||
auto& stream = getReadStream();
|
||||
json j;
|
||||
stream >> j;
|
||||
materialName = j["name"].get<std::string>();
|
||||
layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout");
|
||||
//Shader file needs to conform to the slang standard, which prohibits _
|
||||
materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end());
|
||||
std::ofstream codeStream("./shaders/generated/"+materialName+".slang");
|
||||
std::string profile = j["profile"].get<std::string>();
|
||||
|
||||
codeStream << "import VERTEX_INPUT_IMPORT;" << std::endl;
|
||||
codeStream << "import Material;" << std::endl;
|
||||
codeStream << "import BRDF;" << std::endl;
|
||||
codeStream << "import MaterialParameter;" << std::endl << std::endl;
|
||||
|
||||
codeStream << "struct " << materialName << " : IMaterial {" << std::endl;
|
||||
uint32 uniformBufferOffset = 0;
|
||||
uint32 bindingCounter = 0; // Uniform buffers are always binding 0
|
||||
uniformBinding = -1;
|
||||
for(auto param : j["params"].items())
|
||||
{
|
||||
std::string type = param.value()["type"].get<std::string>();
|
||||
auto defaultValue = param.value().find("default");
|
||||
if(type.compare("float") == 0)
|
||||
{
|
||||
PFloatParameter p = new FloatParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 4;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = std::stof(defaultValue.value().get<std::string>());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("float3") == 0)
|
||||
{
|
||||
PVectorParameter p = new VectorParameter(param.key(), uniformBufferOffset, 0);
|
||||
codeStream << "\tlayout(offset = " << uniformBufferOffset << ")";
|
||||
if(uniformBinding == -1)
|
||||
{
|
||||
layout->addDescriptorBinding(bindingCounter, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER);
|
||||
uniformBinding = bindingCounter++;
|
||||
}
|
||||
uniformBufferOffset += 12;
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
p->data = parseVector(defaultValue.value().get<std::string>().c_str());
|
||||
}
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("Texture2D") == 0)
|
||||
{
|
||||
PTextureParameter p = new TextureParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE);
|
||||
if(defaultValue != param.value().end())
|
||||
{
|
||||
std::string defaultString = defaultValue.value().get<std::string>();
|
||||
p->data = AssetRegistry::findTexture(defaultString);
|
||||
}
|
||||
else
|
||||
{
|
||||
p->data = AssetRegistry::findTexture(""); // this will return placeholder texture
|
||||
}
|
||||
assert(p->data != nullptr);
|
||||
parameters.add(p);
|
||||
}
|
||||
else if(type.compare("SamplerState") == 0)
|
||||
{
|
||||
PSamplerParameter p = new SamplerParameter(param.key(), 0, bindingCounter);
|
||||
layout->addDescriptorBinding(bindingCounter++, Gfx::SE_DESCRIPTOR_TYPE_SAMPLER);
|
||||
SamplerCreateInfo createInfo;
|
||||
p->data = WindowManager::getGraphics()->createSamplerState(createInfo);
|
||||
parameters.add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "Error unsupported parameter type" << std::endl;
|
||||
}
|
||||
codeStream << "\t" << type << " " << param.key() << ";\n";
|
||||
}
|
||||
uniformDataSize = uniformBufferOffset;
|
||||
if(uniformDataSize != 0)
|
||||
{
|
||||
uniformData = new uint8[uniformDataSize];
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
uniformInitializer.resourceData.data = uniformData;
|
||||
uniformInitializer.resourceData.size = uniformDataSize;
|
||||
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
|
||||
}
|
||||
BRDF* brdf = BRDF::getBRDFByName(profile);
|
||||
brdf->generateMaterialCode(codeStream, j["code"]);
|
||||
codeStream << "};";
|
||||
codeStream.close();
|
||||
layout->create();
|
||||
setStatus(Status::Ready);
|
||||
}
|
||||
|
||||
|
||||
void MaterialAsset::beginFrame()
|
||||
{
|
||||
}
|
||||
@@ -48,7 +171,18 @@ void MaterialAsset::updateDescriptorData()
|
||||
descriptorSet->writeChanges();
|
||||
}
|
||||
|
||||
const Gfx::PDescriptorSet MaterialAsset::getDescriptor() const
|
||||
const Gfx::ShaderCollection* MaterialAsset::getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const
|
||||
{
|
||||
return descriptorSet;
|
||||
}
|
||||
Gfx::ShaderPermutation permutation;
|
||||
permutation.passType = renderPass;
|
||||
std::string vertexInputName = vertexInput->getName();
|
||||
std::memcpy(permutation.materialName, materialName.c_str(), sizeof(permutation.materialName));
|
||||
std::memcpy(permutation.vertexInputName, vertexInputName.c_str(), sizeof(permutation.vertexInputName));
|
||||
return shaderMap.findShaders(Gfx::PermutationId(permutation));
|
||||
}
|
||||
|
||||
Gfx::ShaderCollection& MaterialAsset::createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput)
|
||||
{
|
||||
std::unique_lock lock(shaderMapLock);
|
||||
return shaderMap.createShaders(graphics, renderPass, this, vertexInput, false);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_REF(VertexShaderInput)
|
||||
DECLARE_REF(Material)
|
||||
class MaterialAsset : public Asset
|
||||
{
|
||||
public:
|
||||
@@ -16,18 +15,26 @@ public:
|
||||
~MaterialAsset();
|
||||
virtual void beginFrame();
|
||||
virtual void endFrame();
|
||||
virtual void save() = 0;
|
||||
virtual void load() = 0;
|
||||
virtual const Material* getRenderMaterial() const = 0;
|
||||
virtual void save() override;
|
||||
virtual void load() override;
|
||||
Gfx::SeBlendOp getBlendMode() const {return Gfx::SE_BLEND_OP_END_RANGE;}
|
||||
Gfx::MaterialShadingModel getShadingModel() const {return Gfx::MaterialShadingModel::DefaultLit;}
|
||||
|
||||
// This needs to be called while the descriptorset is unused
|
||||
void updateDescriptorData();
|
||||
void resetDescriptorSet();
|
||||
const Gfx::PDescriptorSet getDescriptor() const;
|
||||
const Gfx::PDescriptorSet getDescriptor() const { return descriptorSet; };
|
||||
|
||||
Gfx::PDescriptorLayout getDescriptorLayout() const { return layout; }
|
||||
// The name of the generated material shader, opposed to the name of the .asset file
|
||||
const std::string& getName() {return materialName;}
|
||||
|
||||
const Gfx::ShaderCollection* getShaders(Gfx::RenderPassType renderPass, VertexInputType* vertexInput) const;
|
||||
Gfx::ShaderCollection& createShaders(Gfx::PGraphics graphics, Gfx::RenderPassType renderPass, VertexInputType* vertexInput);
|
||||
private:
|
||||
static Gfx::ShaderMap shaderMap;
|
||||
static std::mutex shaderMapLock;
|
||||
|
||||
protected:
|
||||
//For now its simply the collection of parameters, since there is no point for expressions
|
||||
Array<PShaderParameter> parameters;
|
||||
Gfx::PDescriptorSet descriptorSet;
|
||||
@@ -36,6 +43,7 @@ protected:
|
||||
uint32 uniformDataSize;
|
||||
uint8* uniformData;
|
||||
int32 uniformBinding;
|
||||
std::string materialName;
|
||||
};
|
||||
DEFINE_REF(MaterialAsset)
|
||||
} // namespace Seele
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
#include "MaterialInstance.h"
|
||||
#include "Material.h"
|
||||
#include "Window/WindowManager.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
MaterialInstance::MaterialInstance()
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(const std::string& directory, const std::string& name)
|
||||
: MaterialAsset(directory, name)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::MaterialInstance(const std::filesystem::path& fullPath)
|
||||
: MaterialAsset(fullPath)
|
||||
{
|
||||
}
|
||||
|
||||
MaterialInstance::~MaterialInstance()
|
||||
{
|
||||
}
|
||||
|
||||
void MaterialInstance::save()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MaterialInstance::load()
|
||||
{
|
||||
baseMaterial = nullptr; // TODO: actually load the file
|
||||
UniformBufferCreateInfo uniformInitializer;
|
||||
uniformInitializer.resourceData.size = baseMaterial->uniformDataSize;
|
||||
uniformInitializer.resourceData.data = nullptr;
|
||||
uniformBuffer = WindowManager::getGraphics()->createUniformBuffer(uniformInitializer);
|
||||
}
|
||||
|
||||
const Material* MaterialInstance::getRenderMaterial() const
|
||||
{
|
||||
return baseMaterial;
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
#pragma once
|
||||
#include "MaterialAsset.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
DECLARE_NAME_REF(Gfx, DescriptorSet)
|
||||
DECLARE_REF(Material)
|
||||
class MaterialInstance : public MaterialAsset
|
||||
{
|
||||
public:
|
||||
MaterialInstance();
|
||||
MaterialInstance(const std::string& directory, const std::string& name);
|
||||
MaterialInstance(const std::filesystem::path& fullPath);
|
||||
~MaterialInstance();
|
||||
virtual void save() override;
|
||||
virtual void load() override;
|
||||
virtual const Material* getRenderMaterial() const;
|
||||
private:
|
||||
Material* baseMaterial;
|
||||
};
|
||||
DEFINE_REF(MaterialInstance)
|
||||
} // namespace Seele
|
||||
@@ -9,7 +9,7 @@ CameraComponent::CameraComponent()
|
||||
: bNeedsViewBuild(true)
|
||||
, bNeedsProjectionBuild(true)
|
||||
, originPoint(0, 0, 0)
|
||||
, cameraPosition(0, 0, 0)
|
||||
, cameraPosition(0, 0, 50)
|
||||
{
|
||||
distance = 50;
|
||||
rotationX = 0;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "PrimitiveComponent.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "Asset/MeshAsset.h"
|
||||
#include "Graphics/VertexShaderInput.h"
|
||||
#include <iostream>
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include "Scene.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Components/PrimitiveUniformBufferLayout.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialAsset.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "Graphics/GraphicsResources.h"
|
||||
#include "Components/PrimitiveComponent.h"
|
||||
#include "Graphics/MeshBatch.h"
|
||||
#include "Material/Material.h"
|
||||
#include "SceneUpdater.h"
|
||||
|
||||
namespace Seele
|
||||
|
||||
@@ -31,7 +31,7 @@ RenderHierarchy::~RenderHierarchy()
|
||||
|
||||
void RenderHierarchy::addElement(PElement addedElement)
|
||||
{
|
||||
std::lock_guard lock(updateLock);
|
||||
std::unique_lock lock(updateLock);
|
||||
updates.add(new AddElementRenderHierarchyUpdate{
|
||||
addedElement.getHandle(),
|
||||
addedElement->getParent().getHandle()
|
||||
@@ -40,7 +40,7 @@ void RenderHierarchy::addElement(PElement addedElement)
|
||||
|
||||
void RenderHierarchy::removeElement(PElement elementToRemove)
|
||||
{
|
||||
std::lock_guard lock(updateLock);
|
||||
std::unique_lock lock(updateLock);
|
||||
updates.add(new RemoveElementRenderHierarchyUpdate{
|
||||
elementToRemove.getHandle(),
|
||||
});
|
||||
@@ -48,7 +48,7 @@ void RenderHierarchy::removeElement(PElement elementToRemove)
|
||||
|
||||
void RenderHierarchy::moveElement(PElement elementToMove, PElement newParent)
|
||||
{
|
||||
std::lock_guard lock(updateLock);
|
||||
std::unique_lock lock(updateLock);
|
||||
updates.add(new AddElementRenderHierarchyUpdate{
|
||||
elementToMove.getHandle(),
|
||||
newParent.getHandle()
|
||||
@@ -62,7 +62,7 @@ void RenderHierarchy::updateHierarchy()
|
||||
{
|
||||
List<RenderHierarchyUpdate*> localUpdates;
|
||||
{ // make a local copy of the updates so we dont hold the lock for too long
|
||||
std::lock_guard lock(updateLock);
|
||||
std::unique_lock lock(updateLock);
|
||||
localUpdates = updates;
|
||||
updates.clear();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
target_sources(SeeleEngine
|
||||
PRIVATE
|
||||
Frame.h
|
||||
Frame.cpp
|
||||
InspectorView.h
|
||||
InspectorView.cpp
|
||||
SceneView.h
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
#pragma once
|
||||
#include "View.h"
|
||||
|
||||
namespace Seele
|
||||
{
|
||||
// A frame is the mutable data needed to
|
||||
// process a time step for the game updates
|
||||
// It contains all the game update relevant data
|
||||
// and is handed over to the renderer for read only processing
|
||||
// If the game loop runs faster than the renderer, the renderer
|
||||
// simply discards old Frames and starts working on the more recent ones
|
||||
// if the game loop runs slower than the renderer (bad), the renderer has to wait
|
||||
struct Frame
|
||||
{
|
||||
uint64 frameNumber;
|
||||
Array<PViewFrame> viewFrame;
|
||||
};
|
||||
} // namespace Seele
|
||||
@@ -25,10 +25,10 @@ void Window::render()
|
||||
gfxHandle->beginFrame();
|
||||
for(auto& windowView : views)
|
||||
{
|
||||
{
|
||||
std::lock_guard lock(windowView->workerMutex);
|
||||
windowView->view->prepareRender();
|
||||
}
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
windowView->view->commitUpdate();
|
||||
windowView->view->prepareRender();
|
||||
windowView->view->render();
|
||||
}
|
||||
gfxHandle->endFrame();
|
||||
@@ -58,9 +58,5 @@ void Window::viewWorker(WindowView* windowView)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
windowView->view->beginUpdate();
|
||||
windowView->view->update();
|
||||
std::lock_guard lock(windowView->workerMutex);
|
||||
windowView->view->commitUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user