Finished writeup and fixed crashes
This commit is contained in:
Vendored
+4
-4
@@ -3,22 +3,22 @@
|
||||
{
|
||||
"name": "Win32",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"external/**"
|
||||
"${workspaceFolder}/src/**"
|
||||
],
|
||||
"defines": [
|
||||
"_DEBUG",
|
||||
"UNICODE",
|
||||
"_UNICODE"
|
||||
],
|
||||
"intelliSenseMode": "msvc-x64",
|
||||
"intelliSenseMode": "windows-msvc-x64",
|
||||
"configurationProvider": "ms-vscode.cmake-tools",
|
||||
"cppStandard": "c++20",
|
||||
"browse": {
|
||||
"path": [
|
||||
"external/**"
|
||||
]
|
||||
}
|
||||
},
|
||||
"compilerPath": "C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30037/bin/Hostx64/x64/cl.exe"
|
||||
}
|
||||
],
|
||||
"version": 4
|
||||
|
||||
Vendored
+2
-1
@@ -133,5 +133,6 @@
|
||||
"**/target": true
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Disabled",
|
||||
"git.ignoreSubmodules": true
|
||||
"git.ignoreSubmodules": true,
|
||||
"cmake.configureOnOpen": true
|
||||
}
|
||||
+4
-2
@@ -21,6 +21,7 @@ set(NSAM_ROOT ${EXTERNAL_ROOT}/aftermath)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/)
|
||||
|
||||
set(Boost_USE_STATIC_LIBS OFF)
|
||||
set(Boost_LIB_PREFIX lib)
|
||||
|
||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bin/${CMAKE_BUILD_TYPE})
|
||||
#Workaround for vs, because it places artifacts into an additional subfolder
|
||||
@@ -37,7 +38,6 @@ else()
|
||||
project (Seele)
|
||||
endif()
|
||||
|
||||
|
||||
find_package(Vulkan REQUIRED)
|
||||
find_package(Boost REQUIRED COMPONENTS serialization)
|
||||
find_package(Threads REQUIRED)
|
||||
@@ -117,7 +117,7 @@ if(WIN32)
|
||||
add_custom_target(copy-binaries ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${SLANG_GLSLANG} $<TARGET_FILE_DIR:SeeleEngine>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:SeeleEngine>
|
||||
#COMMAND ${CMAKE_COMMAND} -E copy_if_different ${GLFW_BINARY} $<TARGET_FILE_DIR:SeeleEngine>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${ASSIMP_BINARY} $<TARGET_FILE_DIR:SeeleEngine>
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${NSAM_BINARIES} $<TARGET_FILE_DIR:SeeleEngine>)
|
||||
else()
|
||||
@@ -127,3 +127,5 @@ endif()
|
||||
add_custom_target(copy-runtime-files ALL
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:SeeleEngine>
|
||||
DEPENDS SeeleEngine copy-binaries)
|
||||
|
||||
|
||||
+66
-4
@@ -9,7 +9,7 @@ API that doesn't support it, like OpenGL. These APIs would suffer a significant
|
||||
## Custom containers and other utilities
|
||||
|
||||
Some of the basic containers are reimplemented, mostly not for any particular feature, but because that makes them more customizable and extendable for future uses and
|
||||
performance optimizations, like serialization for example. Due to them occuring in the code samples later, they will be quickly mentioned here.
|
||||
performance optimizations, like serialization for example. Due to some of them occuring in the code samples later, they will be quickly mentioned here.
|
||||
|
||||
- `Array`: A heap-array backed dynamically resizable container, like `std::vector`
|
||||
- `StaticArray`: A static-array backed non-resizable container, like `std::array`
|
||||
@@ -139,8 +139,70 @@ The document starts with the asset `name`, followed by the `profile`, which tell
|
||||
|
||||
### MaterialAsset
|
||||
|
||||
The `MaterialAsset` class represents such a JSON document on disk, and is the base class for `Material` and `MaterialInstance`. It stores the layout of the parameters as well as their values, but does not store, parse or generate any shader code.
|
||||
A `MaterialAsset` represents such a JSON document on disk, as well as the GPU resources needed to render a mesh with the material. When loading the file, the a descriptor layout is generated to fit the `slang` code that will be generated later by consolidating the plain variables (`float`, `double`, etc.) into a single uniform buffer. The parameters are stored in an array of `ShaderParameter`s, which contain the current parameter value, like texture references or plain data, as well as information on how to update the GPU resources.
|
||||
|
||||
### Material
|
||||
At the same time a slang-compilable shader is generated, which matches the parameters provided by the descriptor layout. The generated shader is a `Material`, which is an interface that "prepares" a BRDF by initializing its input values, similar to official slang example. How each input value is calculated is read from the `code` section of the JSON document, and wrapped in an accessor to allow for multi line calculations.
|
||||
|
||||
The `Material` class inherits from `MaterialAsset` and represents a base material,
|
||||
Here is the material generated from the above JSON example:
|
||||
|
||||
```cpp
|
||||
import VERTEX_INPUT_IMPORT;
|
||||
import Material;
|
||||
import BRDF;
|
||||
import MaterialParameter;
|
||||
|
||||
struct Placeholder: IMaterial {
|
||||
layout(offset = 0)float anisotropic;
|
||||
layout(offset = 4)float clearCoat;
|
||||
layout(offset = 8)float clearCoatGloss;
|
||||
Texture2D diffuseTexture;
|
||||
layout(offset = 12)float metallic;
|
||||
Texture2D normalTexture;
|
||||
layout(offset = 16)float roughness;
|
||||
layout(offset = 20)float sheen;
|
||||
layout(offset = 24)float sheenTint;
|
||||
Texture2D specularTexture;
|
||||
layout(offset = 28)float specularTint;
|
||||
layout(offset = 32)float subsurface;
|
||||
SamplerState textureSampler;
|
||||
layout(offset = 36)float uvScale;
|
||||
layout(offset = 40)float3 worldOffset;
|
||||
|
||||
float3 getBaseColor(MaterialFragmentParameter input) {
|
||||
return diffuseTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;;
|
||||
}
|
||||
float getMetallic(MaterialFragmentParameter input) {
|
||||
return 0;;
|
||||
}
|
||||
float3 getNormal(MaterialFragmentParameter input) {
|
||||
return normalTexture.Sample(textureSampler, input.texCoords[0] * uvScale).xyz;;
|
||||
}
|
||||
float getSpecular(MaterialFragmentParameter input) {
|
||||
return specularTexture.Sample(textureSampler, input.texCoords[0] * uvScale).x;;
|
||||
}
|
||||
float getRoughness(MaterialFragmentParameter input) {
|
||||
return roughness;;
|
||||
}
|
||||
float getSheen(MaterialFragmentParameter input) {
|
||||
return sheen;;
|
||||
}
|
||||
float3 getWorldOffset() {
|
||||
return worldOffset;;
|
||||
}
|
||||
typedef BlinnPhong BRDF;
|
||||
BlinnPhong prepare(MaterialFragmentParameter geometry){
|
||||
BlinnPhong result;
|
||||
result.baseColor = getBaseColor(geometry);
|
||||
result.metallic = getMetallic(geometry);
|
||||
result.normal = getNormal(geometry);
|
||||
result.specular = getSpecular(geometry);
|
||||
result.roughness = getRoughness(geometry);
|
||||
result.sheen = getSheen(geometry);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### Renderpass interaction
|
||||
|
||||
Each render pass has a "base file" containing the vertex and fragment stages. From that base file a variant is generated for each material that will be used with that render pass using `#define` macros to change the material import, and a `type_param` to update the `ParameterBlock` containing the material itself. Other renderpass dependent data like camera parameter or lights are stored in separate descriptor sets, and to avoid code duplication, they parts that are used by more than one render pass are implemented in separate slang files. But since in Vulkan pipeline layouts cannot have empty indices, the descriptor set indices sometimes need to change. This is done using the static `modifyRenderPassMacros` function in each renderpass to `#define` the correct set indices for each shared descriptor layout.
|
||||
|
||||
@@ -48,14 +48,15 @@ if (WIN32)
|
||||
|
||||
unset(GLFW_LIBRARY_NAME)
|
||||
|
||||
find_file(
|
||||
GLFW_BINARY
|
||||
NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll
|
||||
PATHS
|
||||
$ENV{PROGRAMFILES}/bin
|
||||
${GLFW_ROOT}/src
|
||||
${GLFW_ROOT}/bin
|
||||
PATH_SUFFIXES Debug Release)
|
||||
#find_file(
|
||||
# GLFW_BINARY
|
||||
# NAMES glfw3${CMAKE_DEBUG_POSTFIX}.dll
|
||||
# PATHS
|
||||
# $ENV{PROGRAMFILES}/bin
|
||||
# ${CMAKE_BINARY_DIR}
|
||||
# ${GLFW_ROOT}/src
|
||||
# ${GLFW_ROOT}/bin
|
||||
# PATH_SUFFIXES Debug Release)
|
||||
else()
|
||||
# Find include files
|
||||
find_path(
|
||||
|
||||
@@ -28,14 +28,13 @@ else()
|
||||
endif()
|
||||
ExternalProject_Add(boost
|
||||
SOURCE_DIR ${BOOST_ROOT}
|
||||
UPDATE_COMMAND ""
|
||||
CONFIGURE_COMMAND ./bootstrap.${BOOTSTRAP_EXTENSION} --with-libraries=serialization,test
|
||||
BUILD_COMMAND ./b2 -d0
|
||||
BUILD_IN_SOURCE 1
|
||||
INSTALL_COMMAND "")
|
||||
|
||||
list (APPEND EXTRA_CMAKE_ARGS
|
||||
-DBoost_NO_SYSTEM_PATHS=OFF)
|
||||
-DBoost_NO_SYSTEM_PATHS=ON)
|
||||
|
||||
#-----------------KTX----------------------------
|
||||
list(APPEND DEPENDENCIES ktx)
|
||||
|
||||
@@ -105,7 +105,8 @@ void cullLights(ComputeShaderInput in)
|
||||
for ( uint i = in.groupIndex; i < numPointLights; i += BLOCK_SIZE * BLOCK_SIZE )
|
||||
{
|
||||
PointLight light = pointLights[i];
|
||||
if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||
//TODO: why doesn't this check go through?
|
||||
//if(light.insideFrustum(groupFrustum, nearClipVS, maxDepthVS))
|
||||
{
|
||||
tAppendLight(i);
|
||||
if(!light.insidePlane(minPlane))
|
||||
|
||||
@@ -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