Refactor material system (#382)

This commit is contained in:
Jérôme Leclercq 2022-10-31 19:53:41 +01:00 committed by GitHub
parent 0a8048809c
commit dc6ce8427c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
156 changed files with 3633 additions and 4569 deletions

View File

@ -9,20 +9,29 @@ option HasAlphaTexture: bool = false;
option AlphaTest: bool = false;
[layout(std140)]
struct BasicSettings
struct MaterialSettings
{
[tag("AlphaTestThreshold")]
AlphaThreshold: f32,
[tag("BaseColor")]
BaseColor: vec4[f32]
}
[tag("Material")]
external
{
[binding(0)] settings: uniform[BasicSettings],
[binding(1)] MaterialBaseColorMap: sampler2D[f32],
[binding(2)] MaterialAlphaMap: sampler2D[f32],
[binding(3)] TextureOverlay: sampler2D[f32],
[binding(4)] instanceData: uniform[InstanceData],
[binding(5)] viewerData: uniform[ViewerData],
[tag("Settings"), binding(0)] settings: uniform[MaterialSettings],
[tag("BaseColorMap"), binding(1)] MaterialBaseColorMap: sampler2D[f32],
[tag("AlphaMap"), binding(2)] MaterialAlphaMap: sampler2D[f32],
}
[tag("Engine")]
external
{
[tag("TextureOverlay"), binding(3)] TextureOverlay: sampler2D[f32],
[tag("InstanceData"), binding(4)] instanceData: uniform[InstanceData],
[tag("ViewerData"), binding(5)] viewerData: uniform[ViewerData],
}
struct InputData

View File

@ -5,17 +5,29 @@ import InstanceData from Engine.InstanceData;
import ViewerData from Engine.ViewerData;
[layout(std140)]
struct BasicSettings
struct MaterialSettings
{
[tag("AlphaTestThreshold")]
AlphaThreshold: f32,
[tag("BaseColor")]
BaseColor: vec4[f32]
}
[tag("Material")]
external
{
[binding(0)] settings: uniform[BasicSettings],
[binding(4)] instanceData: uniform[InstanceData],
[binding(5)] viewerData: uniform[ViewerData],
[tag("Settings"), binding(0)] settings: uniform[MaterialSettings],
[tag("BaseColorMap"), binding(1)] MaterialBaseColorMap: sampler2D[f32],
[tag("AlphaMap"), binding(2)] MaterialAlphaMap: sampler2D[f32],
}
[tag("Engine")]
external
{
[tag("TextureOverlay"), binding(3)] TextureOverlay: sampler2D[f32],
[tag("InstanceData"), binding(4)] instanceData: uniform[InstanceData],
[tag("ViewerData"), binding(5)] viewerData: uniform[ViewerData],
}
struct InputData

View File

@ -192,60 +192,49 @@ int main()
std::shared_ptr<Nz::GraphicalMesh> coneMeshGfx = Nz::GraphicalMesh::BuildFromMesh(*coneMesh);
auto customSettings = Nz::BasicMaterial::GetSettings()->GetBuilderData();
customSettings.shaders.clear();
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Fragment, nzsl::ParseFromFile(shaderDir / "deferred_frag.nzsl")));
customSettings.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Vertex, nzsl::ParseFromFile(shaderDir / "deferred_vert.nzsl")));
Nz::MaterialSettings settings;
Nz::PredefinedMaterials::AddBasicSettings(settings);
auto customMatSettings = std::make_shared<Nz::MaterialSettings>(std::move(customSettings));
Nz::MaterialPass customForwardPass;
customForwardPass.states.depthBuffer = true;
customForwardPass.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Fragment, nzsl::ParseFromFile(shaderDir / "deferred_frag.nzsl")));
customForwardPass.shaders.emplace_back(std::make_shared<Nz::UberShader>(nzsl::ShaderStageType::Vertex, nzsl::ParseFromFile(shaderDir / "deferred_vert.nzsl")));
settings.AddPass("ForwardPass", customForwardPass);
std::shared_ptr<Nz::Material> spaceshipMat = std::make_shared<Nz::Material>();
Nz::MaterialPass customDepthPass = customForwardPass;
customDepthPass.options[Nz::CRC32("DepthPass")] = true;
settings.AddPass("DepthPass", customDepthPass);
std::shared_ptr<Nz::MaterialPass> spaceshipMatPass = std::make_shared<Nz::MaterialPass>(customMatSettings);
spaceshipMatPass->EnableDepthBuffer(true);
auto deferredMaterial = std::make_shared<Nz::Material>(std::move(settings), "BasicMaterial");
std::shared_ptr<Nz::MaterialInstance> spaceshipMat = deferredMaterial->CreateInstance();
spaceshipMat->SetTextureProperty("AlphaMap", Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
spaceshipMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
std::shared_ptr<Nz::MaterialInstance> flareMaterial = deferredMaterial->CreateInstance();
flareMaterial->UpdatePassStates("ForwardPass", [](Nz::RenderStates& renderStates)
{
Nz::BasicMaterial basicMat(*spaceshipMatPass);
basicMat.EnableAlphaTest(false);
basicMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
}
spaceshipMat->AddPass("ForwardPass", spaceshipMatPass);
renderStates.depthClamp = true;
renderStates.depthWrite = false;
renderStates.blending = true;
renderStates.blend.modeColor = Nz::BlendEquation::Add;
renderStates.blend.modeAlpha = Nz::BlendEquation::Add;
renderStates.blend.srcColor = Nz::BlendFunc::SrcAlpha;
renderStates.blend.dstColor = Nz::BlendFunc::InvSrcAlpha;
renderStates.blend.srcAlpha = Nz::BlendFunc::One;
renderStates.blend.dstAlpha = Nz::BlendFunc::One;
return true;
});
flareMaterial->UpdatePassFlags("ForwardPass", Nz::MaterialPassFlag::SortByDistance);
flareMaterial->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "flare1.png", texParams));
std::shared_ptr<Nz::Material> flareMaterial = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> flareMaterialPass;
{
flareMaterialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
flareMaterialPass->EnableDepthBuffer(true);
flareMaterialPass->EnableDepthWrite(false);
flareMaterialPass->EnableDepthClamp(true);
Nz::TextureSamplerInfo planeSampler;
planeSampler.anisotropyLevel = 16;
planeSampler.wrapModeU = Nz::SamplerWrap::Repeat;
planeSampler.wrapModeV = Nz::SamplerWrap::Repeat;
flareMaterialPass->EnableFlag(Nz::MaterialPassFlag::SortByDistance);
flareMaterialPass->EnableBlending(true);
flareMaterialPass->SetBlendEquation(Nz::BlendEquation::Add, Nz::BlendEquation::Add);
flareMaterialPass->SetBlendFunc(Nz::BlendFunc::SrcAlpha, Nz::BlendFunc::InvSrcAlpha, Nz::BlendFunc::One, Nz::BlendFunc::Zero);
Nz::BasicMaterial Osef(*flareMaterialPass);
Osef.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "flare1.png", texParams));
flareMaterial->AddPass("ForwardPass", flareMaterialPass);
}
std::shared_ptr<Nz::Material> planeMat = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> planeMatPass = std::make_shared<Nz::MaterialPass>(customMatSettings);
planeMatPass->EnableDepthBuffer(true);
{
Nz::BasicMaterial basicMat(*planeMatPass);
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams));
Nz::TextureSamplerInfo planeSampler;
planeSampler.anisotropyLevel = 16;
planeSampler.wrapModeU = Nz::SamplerWrap::Repeat;
planeSampler.wrapModeV = Nz::SamplerWrap::Repeat;
basicMat.SetBaseColorSampler(planeSampler);
}
planeMat->AddPass("ForwardPass", planeMatPass);
std::shared_ptr<Nz::MaterialInstance> planeMat = deferredMaterial->CreateInstance();
planeMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams), planeSampler);
Nz::Model spaceshipModel(std::move(gfxMesh), spaceship->GetAABB());
for (std::size_t i = 0; i < spaceshipModel.GetSubMeshCount(); ++i)
@ -537,7 +526,7 @@ int main()
std::shared_ptr<Nz::ShaderBinding> godRaysShaderBinding = godraysPipelineInfo.pipelineLayout->AllocateShaderBinding(0);
/*
uniformExposure = 0.0034f;
uniformExposure = 0.0034f;
uniformDecay = 1.0f;
uniformDensity = 0.84f;
uniformWeight = 5.65f;
@ -588,7 +577,7 @@ int main()
meshPrimitiveParams.vertexDeclaration
});
stencilPipelineInfo.colorWrite = false;
stencilPipelineInfo.colorWriteMask = 0;
stencilPipelineInfo.depthBuffer = true;
stencilPipelineInfo.depthWrite = false;
stencilPipelineInfo.faceCulling = false;
@ -1466,15 +1455,15 @@ int main()
{
builder.PreTransferBarrier();
modelInstance1.UpdateBuffers(uploadPool, builder);
modelInstance2.UpdateBuffers(uploadPool, builder);
planeInstance.UpdateBuffers(uploadPool, builder);
modelInstance1.OnTransfer(frame, builder);
modelInstance2.OnTransfer(frame, builder);
planeInstance.OnTransfer(frame, builder);
Nz::EulerAnglesf flareRotation(0.f, 0.f, elapsedTime * 10.f);
flareInstance.UpdateWorldMatrix(Nz::Matrix4f::Transform(viewerPos + flarePosition, flareRotation));
flareInstance.UpdateBuffers(uploadPool, builder);
flareInstance.OnTransfer(frame, builder);
viewerInstance.UpdateBuffers(uploadPool, builder);
viewerInstance.OnTransfer(frame, builder);
// Update light buffer
if (!spotLights.empty() && (lightUpdate || lightAnimation))
@ -1527,9 +1516,9 @@ int main()
builder.CopyBuffer(lightScatteringAllocation, godRaysUBO.get());
}
spaceshipMatPass->Update(frame, builder);
planeMatPass->Update(frame, builder);
flareMaterialPass->Update(frame, builder);
spaceshipMat->OnTransfer(frame, builder);
planeMat->OnTransfer(frame, builder);
flareMaterial->OnTransfer(frame, builder);
builder.PostTransferBarrier();
}

View File

@ -1,6 +1,8 @@
#include <Nazara/Core.hpp>
#include <Nazara/Platform.hpp>
#include <Nazara/Graphics.hpp>
#include <Nazara/Graphics/PropertyHandler/TexturePropertyHandler.hpp>
#include <Nazara/Graphics/PropertyHandler/UniformValuePropertyHandler.hpp>
#include <Nazara/Renderer.hpp>
#include <Nazara/Utility.hpp>
#include <array>
@ -19,7 +21,7 @@ int main()
if (std::getchar() == 'y')
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
else
rendererConfig.preferredAPI = Nz::RenderAPI::OpenGL;
rendererConfig.preferredAPI = Nz::RenderAPI::Vulkan;
Nz::Modules<Nz::Graphics> nazara(rendererConfig);
@ -61,30 +63,25 @@ int main()
texParams.renderDevice = device;
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::Texture> diffuseTexture = Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams);
std::shared_ptr<Nz::MaterialPass> forwardPass = std::make_shared<Nz::MaterialPass>(Nz::PhongLightingMaterial::GetSettings());
forwardPass->EnableDepthBuffer(true);
forwardPass->EnableFaceCulling(true);
std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicMaterial;
material->AddPass("ForwardPass", forwardPass);
std::shared_ptr<Nz::MaterialInstance> materialInstance = std::make_shared<Nz::MaterialInstance>(material);
materialInstance->SetTextureProperty(0, diffuseTexture);
materialInstance->SetValueProperty(0, Nz::Color::White);
std::shared_ptr<Nz::Texture> normalMap = Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/normal.png", texParams);
Nz::PhongLightingMaterial phongMat(*forwardPass);
phongMat.EnableAlphaTest(false);
phongMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
phongMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
phongMat.SetNormalMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/normal.png", texParams));
std::shared_ptr<Nz::MaterialInstance> materialInstance2 = std::make_shared<Nz::MaterialInstance>(material);
materialInstance2->SetValueProperty(0, Nz::Color::Green);
Nz::Model model(std::move(gfxMesh), spaceshipMesh->GetAABB());
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
model.SetMaterial(i, material);
model.SetMaterial(i, materialInstance);
Nz::Vector2ui windowSize = window.GetSize();
Nz::Camera camera(window.GetRenderTarget());
//camera.UpdateClearColor(Nz::Color::Gray);
camera.UpdateClearColor(Nz::Color::Gray);
Nz::ViewerInstance& viewerInstance = camera.GetViewerInstance();
viewerInstance.UpdateTargetSize(Nz::Vector2f(window.GetSize()));
@ -138,18 +135,18 @@ int main()
case Nz::WindowEventType::KeyPressed:
if (event.key.virtualKey == Nz::Keyboard::VKey::A)
phongMat.EnableAlphaTest(!phongMat.IsAlphaTestEnabled());
else if (event.key.virtualKey == Nz::Keyboard::VKey::N)
{
if (phongMat.GetNormalMap())
phongMat.SetNormalMap({});
else
phongMat.SetNormalMap(normalMap);
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
model.SetMaterial(i, materialInstance);
}
else if (event.key.virtualKey == Nz::Keyboard::VKey::B)
{
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
model.SetMaterial(i, materialInstance2);
}
else if (event.key.virtualKey == Nz::Keyboard::VKey::Space)
{
modelInstance->UpdateWorldMatrix(Nz::Matrix4f::Translate(viewerPos));
framePipeline.InvalidateWorldInstance(worldInstanceIndex1);
}
break;
@ -227,8 +224,6 @@ int main()
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::TransformInverse(viewerPos, camAngles));
viewerInstance.UpdateEyePosition(viewerPos);
framePipeline.InvalidateViewer(cameraIndex);
framePipeline.Render(frame);
frame.Present();

View File

@ -55,27 +55,22 @@ int main()
Nz::TextureParams srgbTexParams = texParams;
srgbTexParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> forwardPass = std::make_shared<Nz::MaterialPass>(Nz::PhysicallyBasedMaterial::GetSettings());
forwardPass->EnableDepthBuffer(true);
forwardPass->EnableFaceCulling(true);
material->AddPass("ForwardPass", forwardPass);
std::shared_ptr<Nz::Texture> normalMap = Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_normal.png", texParams);
Nz::PhysicallyBasedMaterial pbrMat(*forwardPass);
pbrMat.EnableAlphaTest(false);
pbrMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
pbrMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_basecolor.png", srgbTexParams));
pbrMat.SetMetallicMap(Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_metallic.png", texParams));
pbrMat.SetRoughnessMap(Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_roughness.png", texParams));
pbrMat.SetNormalMap(normalMap);
std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().pbrMaterial;
std::shared_ptr<Nz::MaterialInstance> materialInstance = std::make_shared<Nz::MaterialInstance>(material);
materialInstance->SetTextureProperty("AlphaMap", Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
materialInstance->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_basecolor.png", texParams));
materialInstance->SetTextureProperty("MetallicMap", Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_metallic.png", texParams));
materialInstance->SetTextureProperty("RoughnessMap", Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_roughness.png", texParams));
std::size_t normalMapProperty = materialInstance->FindTextureProperty("NormalMap");
materialInstance->SetTextureProperty(normalMapProperty, normalMap);
Nz::Model model(std::move(gfxMesh), sphereMesh->GetAABB());
for (std::size_t i = 0; i < model.GetSubMeshCount(); ++i)
model.SetMaterial(i, material);
model.SetMaterial(i, materialInstance);
Nz::Vector2ui windowSize = window.GetSize();
@ -129,10 +124,10 @@ int main()
case Nz::WindowEventType::KeyPressed:
if (event.key.virtualKey == Nz::Keyboard::VKey::N)
{
if (pbrMat.GetNormalMap())
pbrMat.SetNormalMap({});
if (materialInstance->GetTextureProperty(normalMapProperty))
materialInstance->SetTextureProperty(normalMapProperty, {});
else
pbrMat.SetNormalMap(normalMap);
materialInstance->SetTextureProperty(normalMapProperty, normalMap);
}
break;
@ -207,8 +202,6 @@ int main()
viewerInstance.UpdateViewMatrix(Nz::Matrix4f::TransformInverse(viewerPos, camAngles));
viewerInstance.UpdateEyePosition(viewerPos);
framePipeline.InvalidateViewer(cameraIndex);
framePipeline.Render(frame);
frame.Present();

View File

@ -52,7 +52,7 @@ int main()
Nz::Vector2ui windowSize = window.GetSize();
physSytem.GetPhysWorld().SetGravity({ 0.f, -9.81f });
physSytem.GetPhysWorld().SetGravity({ 0.f, -98.1f });
entt::entity viewer = registry.create();
{
@ -62,11 +62,6 @@ int main()
cameraComponent.UpdateClearColor(Nz::Color(0.5f, 0.5f, 0.5f));
}
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
material->AddPass("ForwardPass", materialPass);
Nz::TextureSamplerInfo samplerInfo;
samplerInfo.anisotropyLevel = 8;
@ -74,9 +69,8 @@ int main()
texParams.renderDevice = device;
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
Nz::BasicMaterial basicMat(*materialPass);
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
basicMat.SetBaseColorSampler(samplerInfo);
std::shared_ptr<Nz::MaterialInstance> material = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->CreateInstance();
material->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
for (std::size_t y = 0; y < 10; ++y)
{
@ -99,12 +93,7 @@ int main()
entt::entity groundEntity = registry.create();
{
std::shared_ptr<Nz::Material> whiteMaterial = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
whiteMaterial->AddPass("ForwardPass", materialPass);
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(whiteMaterial);
std::shared_ptr<Nz::Sprite> sprite = std::make_shared<Nz::Sprite>(Nz::Graphics::Instance()->GetDefaultMaterials().basicDefault);
sprite->SetSize({ 800.f, 20.f });
sprite->SetOrigin({ 400.f, 10.f, 0.f });
@ -158,13 +147,6 @@ int main()
}
}
if (updateClock.GetMilliseconds() > 1000 / 60)
{
float updateTime = updateClock.Restart() / 1'000'000.f;
physSytem.Update(1000.f / 60.f);
}
systemGraph.Update();
fps++;

View File

@ -56,22 +56,6 @@ int main()
const Nz::Boxf& spaceshipAABB = spaceshipMesh->GetAABB();
std::shared_ptr<Nz::GraphicalMesh> gfxMesh = Nz::GraphicalMesh::BuildFromMesh(*spaceshipMesh);
// Texture
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> depthPass = std::make_shared<Nz::MaterialPass>(Nz::DepthMaterial::GetSettings());
depthPass->EnableDepthBuffer(true);
depthPass->EnableDepthClamp(true);
depthPass->EnableFaceCulling(true);
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::PhongLightingMaterial::GetSettings());
materialPass->EnableDepthBuffer(true);
materialPass->EnableDepthClamp(true);
materialPass->EnableFaceCulling(true);
material->AddPass("DepthPass", depthPass);
material->AddPass("ForwardPass", materialPass);
Nz::TextureSamplerInfo samplerInfo;
samplerInfo.anisotropyLevel = 8;
@ -79,35 +63,15 @@ int main()
texParams.renderDevice = device;
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
Nz::BasicMaterial basicMat(*materialPass);
basicMat.EnableAlphaTest(false);
basicMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
basicMat.SetBaseColorSampler(samplerInfo);
Nz::DepthMaterial basicMatDepth(*depthPass);
basicMatDepth.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
std::shared_ptr<Nz::MaterialInstance> material = Nz::Graphics::Instance()->GetDefaultMaterials().phongMaterial->CreateInstance();
material->SetTextureProperty("AlphaMap", Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
material->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
std::shared_ptr<Nz::Model> model = std::make_shared<Nz::Model>(std::move(gfxMesh), spaceshipAABB);
for (std::size_t i = 0; i < model->GetSubMeshCount(); ++i)
model->SetMaterial(i, material);
std::shared_ptr<Nz::Material> spriteMaterial = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> spriteMaterialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
spriteMaterialPass->EnableDepthBuffer(true);
spriteMaterialPass->EnableDepthWrite(false);
spriteMaterialPass->EnableDepthClamp(true);
spriteMaterialPass->EnableFlag(Nz::MaterialPassFlag::SortByDistance);
spriteMaterialPass->EnableBlending(true);
spriteMaterialPass->SetBlendEquation(Nz::BlendEquation::Add, Nz::BlendEquation::Add);
spriteMaterialPass->SetBlendFunc(Nz::BlendFunc::SrcAlpha, Nz::BlendFunc::InvSrcAlpha, Nz::BlendFunc::One, Nz::BlendFunc::Zero);
spriteMaterial->AddPass("ForwardPass", spriteMaterialPass);
std::shared_ptr<Nz::TextSprite> sprite = std::make_shared<Nz::TextSprite>(spriteMaterial);
std::shared_ptr<Nz::TextSprite> sprite = std::make_shared<Nz::TextSprite>();
sprite->Update(Nz::SimpleTextDrawer::Draw("Voix ambiguë d'un cœur qui, au zéphyr, préfère les jattes de kiwis", 72), 0.01f);
Nz::VertexMapper vertexMapper(*spaceshipMesh->GetSubMesh(0));
@ -134,16 +98,16 @@ int main()
auto shipCollider = std::make_shared<Nz::ConvexCollider3D>(vertices, vertexMapper.GetVertexCount(), 0.01f);
std::shared_ptr<Nz::Material> colliderMat = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> colliderMatPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
colliderMatPass->EnableDepthBuffer(true);
colliderMatPass->SetPrimitiveMode(Nz::PrimitiveMode::LineList);
colliderMat->AddPass("ForwardPass", colliderMatPass);
Nz::BasicMaterial colliderBasicMat(*colliderMatPass);
colliderBasicMat.SetBaseColor(Nz::Color::Green);
std::shared_ptr<Nz::MaterialInstance> colliderMat = Nz::Graphics::Instance()->GetDefaultMaterials().basicMaterial->CreateInstance();
colliderMat->SetValueProperty("BaseColor", Nz::Color::Green);
for (std::string_view passName : { "DepthPass", "ForwardPass" })
{
colliderMat->UpdatePassStates(passName, [](Nz::RenderStates& states)
{
states.primitiveMode = Nz::PrimitiveMode::LineList;
return true;
});
}
std::shared_ptr<Nz::Model> colliderModel;
{
@ -245,9 +209,8 @@ int main()
case Nz::WindowEventType::KeyPressed:
if (event.key.virtualKey == Nz::Keyboard::VKey::A)
{
//canvas2D.Resize({ 1920.f, 1080.f });
basicMat.EnableAlphaTest(!basicMat.IsAlphaTestEnabled());
basicMatDepth.EnableAlphaTest(!basicMatDepth.IsAlphaTestEnabled());
bool alphaTestEnabled = std::get<bool>(*material->GetValueProperty("AlphaTest"));
material->SetValueProperty("AlphaTest", !alphaTestEnabled);
}
else if (event.key.virtualKey == Nz::Keyboard::VKey::B)
{

View File

@ -111,13 +111,18 @@ int main()
const Nz::Boxf& bobAABB = bobMesh->GetAABB();
std::shared_ptr<Nz::GraphicalMesh> bobGfxMesh = Nz::GraphicalMesh::BuildFromMesh(*bobMesh);
std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicMaterial;
std::shared_ptr<Nz::Model> bobModel = std::make_shared<Nz::Model>(std::move(bobGfxMesh), bobAABB);
std::vector<std::shared_ptr<Nz::Material>> materials(bobMesh->GetMaterialCount());
std::vector<std::shared_ptr<Nz::MaterialInstance>> materials(bobMesh->GetMaterialCount());
for (std::size_t i = 0; i < bobMesh->GetMaterialCount(); ++i)
{
materials[i] = std::make_shared<Nz::MaterialInstance>(material);
std::string matPath = bobMesh->GetMaterialData(i).GetStringParameter(Nz::MaterialData::BaseColorTexturePath).GetValueOr("");
if (!matPath.empty())
materials[i] = Nz::Material::LoadFromFile(matPath);
materials[i]->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(matPath, texParams));
}
for (std::size_t i = 0; i < bobMesh->GetSubMeshCount(); ++i)
@ -148,7 +153,7 @@ int main()
auto& bobNode = bobEntity.emplace<Nz::NodeComponent>();
//bobNode.SetRotation(Nz::EulerAnglesf(-90.f, -90.f, 0.f));
//bobNode.SetScale(1.f / 40.f * 0.5f);
//bobNode.SetPosition(bobNode.GetScale() * Nz::Vector3f(0.f, -bobAABB.height / 2.f + bobAABB.y, 0.f));
//bobNode.SetPosition(Nz::Vector3f(0.f, -1.f, 0.f));
auto& bobGfx = bobEntity.emplace<Nz::GraphicsComponent>();
bobGfx.AttachRenderable(bobModel, 0xFFFFFFFF);
@ -173,24 +178,12 @@ int main()
Nz::TextureParams srgbTexParams = texParams;
srgbTexParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> forwardPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
forwardPass->EnableDepthBuffer(true);
forwardPass->EnableFaceCulling(true);
material->AddPass("ForwardPass", forwardPass);
std::shared_ptr<Nz::Texture> normalMap = Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_normal.png", texParams);
Nz::BasicMaterial pbrMat(*forwardPass);
pbrMat.EnableAlphaTest(false);
pbrMat.SetAlphaMap(Nz::Texture::LoadFromFile(resourceDir / "alphatile.png", texParams));
pbrMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_basecolor.png", srgbTexParams));
std::shared_ptr<Nz::MaterialInstance> sphereMat = std::make_shared<Nz::MaterialInstance>(material);
sphereMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Rusty/rustediron2_basecolor.png", srgbTexParams));
std::shared_ptr<Nz::Model> sphereModel = std::make_shared<Nz::Model>(std::move(gfxMesh), sphereMesh->GetAABB());
for (std::size_t i = 0; i < sphereModel->GetSubMeshCount(); ++i)
sphereModel->SetMaterial(i, material);
sphereModel->SetMaterial(i, sphereMat);
auto& sphereNode = registry.emplace<Nz::NodeComponent>(sphereEntity);
sphereNode.SetScale(0.1f);
@ -229,32 +222,24 @@ int main()
std::shared_ptr<Nz::GraphicalMesh> planeMeshGfx = Nz::GraphicalMesh::BuildFromMesh(planeMesh);
std::shared_ptr<Nz::Material> planeMat = std::make_shared<Nz::Material>();
Nz::TextureSamplerInfo planeSampler;
planeSampler.anisotropyLevel = 16;
planeSampler.wrapModeU = Nz::SamplerWrap::Repeat;
planeSampler.wrapModeV = Nz::SamplerWrap::Repeat;
std::shared_ptr<Nz::MaterialPass> planeMatPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
planeMatPass->EnableDepthBuffer(true);
{
Nz::BasicMaterial basicMat(*planeMatPass);
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams));
Nz::TextureSamplerInfo planeSampler;
planeSampler.anisotropyLevel = 16;
planeSampler.wrapModeU = Nz::SamplerWrap::Repeat;
planeSampler.wrapModeV = Nz::SamplerWrap::Repeat;
basicMat.SetBaseColorSampler(planeSampler);
}
planeMat->AddPass("ForwardPass", planeMatPass);
std::shared_ptr<Nz::MaterialInstance> planeMat = std::make_shared<Nz::MaterialInstance>(material);
planeMat->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "dev_grey.png", texParams), planeSampler);
std::shared_ptr<Nz::Model> planeModel = std::make_shared<Nz::Model>(std::move(planeMeshGfx), planeMesh.GetAABB());
planeModel->SetMaterial(0, planeMat);
auto& planeGfx = registry.emplace<Nz::GraphicsComponent>(planeEntity);
planeGfx.AttachRenderable(planeModel, 0xFFFFFFFF);
auto& planeNode = registry.emplace<Nz::NodeComponent>(planeEntity);
auto& planeBody = registry.emplace<Nz::RigidBody3DComponent>(planeEntity, &physSytem.GetPhysWorld());
planeBody.SetGeom(std::make_shared<Nz::BoxCollider3D>(Nz::Vector3f(planeSize.x, 0.5f, planeSize.y), Nz::Vector3f(0.f, -0.25f, 0.f)));
auto& planeGfx = registry.emplace<Nz::GraphicsComponent>(planeEntity);
planeGfx.AttachRenderable(planeModel, 0xFFFFFFFF);
}
window.EnableEventPolling(true);
@ -266,6 +251,8 @@ int main()
Nz::EulerAnglesf camAngles = Nz::EulerAnglesf(-30.f, 0.f, 0.f);
Nz::UInt64 lastTime = Nz::GetElapsedMicroseconds();
Nz::UInt64 fps = 0;
bool paused = false;
while (window.IsOpen())
{
Nz::UInt64 now = Nz::GetElapsedMicroseconds();
@ -282,7 +269,12 @@ int main()
break;
case Nz::WindowEventType::KeyPressed:
{
if (event.type == Nz::WindowEventType::KeyPressed && event.key.virtualKey == Nz::Keyboard::VKey::P)
paused = !paused;
break;
}
case Nz::WindowEventType::MouseMoved:
{
@ -329,20 +321,23 @@ int main()
if (Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::Right) || Nz::Keyboard::IsKeyPressed(Nz::Keyboard::VKey::D))
playerBody.AddForce(Nz::Vector3f::Right() * 25.f * mass, Nz::CoordSys::Local);
incr += updateTime * bobAnim->GetSequence(0)->frameRate * 1.5f;
while (incr >= 1.f)
if (!paused)
{
incr -= 1.f;
incr += updateTime * bobAnim->GetSequence(0)->frameRate * 1.5f;
while (incr >= 1.f)
{
incr -= 1.f;
currentFrame = nextFrame;
nextFrame++;
if (nextFrame >= bobAnim->GetFrameCount())
nextFrame = 0;
currentFrame = nextFrame;
nextFrame++;
if (nextFrame >= bobAnim->GetFrameCount())
nextFrame = 0;
}
std::cout << currentFrame << std::endl;
bobAnim->AnimateSkeleton(skeleton.get(), currentFrame, nextFrame, incr);
}
std::cout << currentFrame << std::endl;
bobAnim->AnimateSkeleton(skeleton.get(), currentFrame, nextFrame, incr);
//for (std::size_t i = 0; i < skeleton.GetJointCount(); ++i)
// matrices[i] = skeleton.GetJoint(i)->GetSkinningMatrix();

View File

@ -33,20 +33,7 @@ int main()
textDrawer.SetOutlineThickness(4.f);
textDrawer.SetText("Hello world !");
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
materialPass->EnableDepthBuffer(true);
materialPass->EnableDepthWrite(false);
materialPass->EnableScissorTest(true);
materialPass->EnableBlending(true);
materialPass->SetBlendEquation(Nz::BlendEquation::Add, Nz::BlendEquation::Add);
materialPass->SetBlendFunc(Nz::BlendFunc::SrcAlpha, Nz::BlendFunc::InvSrcAlpha, Nz::BlendFunc::One, Nz::BlendFunc::One);
material = std::make_shared<Nz::Material>();
material->AddPass("ForwardPass", materialPass);
std::shared_ptr<Nz::TextSprite> textSprite = std::make_shared<Nz::TextSprite>(material);
std::shared_ptr<Nz::TextSprite> textSprite = std::make_shared<Nz::TextSprite>();
textSprite->Update(textDrawer);
entt::entity textEntity = registry.create();

View File

@ -33,20 +33,7 @@ int main()
textDrawer.SetOutlineThickness(4.f);
textDrawer.SetText("Press a key");
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
materialPass->EnableDepthBuffer(true);
materialPass->EnableDepthWrite(false);
materialPass->EnableScissorTest(true);
materialPass->EnableBlending(true);
materialPass->SetBlendEquation(Nz::BlendEquation::Add, Nz::BlendEquation::Add);
materialPass->SetBlendFunc(Nz::BlendFunc::SrcAlpha, Nz::BlendFunc::InvSrcAlpha, Nz::BlendFunc::One, Nz::BlendFunc::One);
material = std::make_shared<Nz::Material>();
material->AddPass("ForwardPass", materialPass);
std::shared_ptr<Nz::TextSprite> textSprite = std::make_shared<Nz::TextSprite>(material);
std::shared_ptr<Nz::TextSprite> textSprite = std::make_shared<Nz::TextSprite>();
textSprite->Update(textDrawer);
entt::entity textEntity = registry.create();

View File

@ -66,10 +66,7 @@ int main()
labelWidget->UpdateText(Nz::SimpleTextDrawer::Draw("You clicked the button " + std::to_string(++clickCount) + " times", 72));
});
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>();
std::shared_ptr<Nz::MaterialPass> materialPass = std::make_shared<Nz::MaterialPass>(Nz::BasicMaterial::GetSettings());
material->AddPass("ForwardPass", materialPass);
std::shared_ptr<Nz::Material> material = Nz::Graphics::Instance()->GetDefaultMaterials().basicMaterial;
Nz::TextureSamplerInfo samplerInfo;
samplerInfo.anisotropyLevel = 8;
@ -78,15 +75,14 @@ int main()
texParams.renderDevice = device;
texParams.loadFormat = Nz::PixelFormat::RGBA8_SRGB;
Nz::BasicMaterial basicMat(*materialPass);
basicMat.SetBaseColorMap(Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
basicMat.SetBaseColorSampler(samplerInfo);
std::shared_ptr<Nz::MaterialInstance> materialInstance = material->CreateInstance();
materialInstance->SetTextureProperty("BaseColorMap", Nz::Texture::LoadFromFile(resourceDir / "Spaceship/Texture/diffuse.png", texParams));
Nz::ImageWidget* imageWidget = canvas2D.Add<Nz::ImageWidget>(material);
Nz::ImageWidget* imageWidget = canvas2D.Add<Nz::ImageWidget>(materialInstance);
imageWidget->SetPosition(1200.f, 200.f);
imageWidget->Resize(imageWidget->GetPreferredSize() / 4.f);
Nz::ImageButtonWidget* imageButtonWidget = canvas2D.Add<Nz::ImageButtonWidget>(material);
Nz::ImageButtonWidget* imageButtonWidget = canvas2D.Add<Nz::ImageButtonWidget>(materialInstance);
imageButtonWidget->SetPosition(1400, 500.f);
imageButtonWidget->Resize(imageButtonWidget->GetPreferredSize() / 4.f);

View File

@ -13,7 +13,7 @@ namespace Nz
inline bool EndsWith(const std::string_view& str, const std::string_view& s)
{
//FIXME: Replace with proper C++20 value once it's available
#if __cplusplus > 201703L
#if NAZARA_CPP_VER > 201703L
// C++20
return str.ends_with(s);
#else
@ -53,7 +53,7 @@ namespace Nz
inline bool StartsWith(const std::string_view& str, const std::string_view& s)
{
//FIXME: Replace with proper C++20 value once it's available
#if __cplusplus > 201703L
#if NAZARA_CPP_VER > 201703L
// C++20
return str.starts_with(s);
#else

View File

@ -32,11 +32,9 @@
#include <Nazara/Graphics/AbstractViewer.hpp>
#include <Nazara/Graphics/Algorithm.hpp>
#include <Nazara/Graphics/BakedFrameGraph.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/Camera.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/DebugDrawPipelinePass.hpp>
#include <Nazara/Graphics/DepthMaterial.hpp>
#include <Nazara/Graphics/DepthPipelinePass.hpp>
#include <Nazara/Graphics/DirectionalLight.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp>
@ -56,15 +54,16 @@
#include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/LinearSlicedSprite.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Graphics/Model.hpp>
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
#include <Nazara/Graphics/PhysicallyBasedMaterial.hpp>
#include <Nazara/Graphics/PointLight.hpp>
#include <Nazara/Graphics/PredefinedMaterials.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Graphics/RenderBufferPool.hpp>
#include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
@ -72,6 +71,7 @@
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Graphics/RenderSpriteChain.hpp>
#include <Nazara/Graphics/RenderSubmesh.hpp>
#include <Nazara/Graphics/ShaderReflection.hpp>
#include <Nazara/Graphics/SkeletonInstance.hpp>
#include <Nazara/Graphics/SlicedSprite.hpp>
#include <Nazara/Graphics/SpotLight.hpp>
@ -80,6 +80,7 @@
#include <Nazara/Graphics/SubmeshRenderer.hpp>
#include <Nazara/Graphics/TextSprite.hpp>
#include <Nazara/Graphics/TextureSamplerCache.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Graphics/ViewerInstance.hpp>
#include <Nazara/Graphics/WorldInstance.hpp>

View File

@ -1,123 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_BASICMATERIAL_HPP
#define NAZARA_GRAPHICS_BASICMATERIAL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
namespace nzsl
{
class FieldOffsets;
}
namespace Nz
{
class NAZARA_GRAPHICS_API BasicMaterial
{
friend class MaterialPipeline;
public:
struct BasicUniformOffsets;
BasicMaterial(MaterialPass& material);
~BasicMaterial() = default;
inline void EnableAlphaTest(bool alphaTest);
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
inline const TextureSamplerInfo& GetAlphaSampler() const;
float GetAlphaTestThreshold() const;
Color GetBaseColor() const;
inline const std::shared_ptr<Texture>& GetBaseColorMap() const;
inline const TextureSamplerInfo& GetBaseColorSampler() const;
inline bool IsAlphaTestEnabled() const;
inline bool HasAlphaMap() const;
inline bool HasAlphaTest() const;
inline bool HasAlphaTestThreshold() const;
inline bool HasBaseColor() const;
inline bool HasBaseColorMap() const;
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
inline void SetAlphaSampler(TextureSamplerInfo alphaSampler);
void SetAlphaTestThreshold(float alphaThreshold);
void SetBaseColor(const Color& baseColor);
inline void SetBaseColorMap(std::shared_ptr<Texture> baseColorMap);
inline void SetBaseColorSampler(TextureSamplerInfo baseColorSampler);
static inline const BasicUniformOffsets& GetOffsets();
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
struct BasicUniformOffsets
{
std::size_t alphaThreshold;
std::size_t baseColor;
std::size_t totalSize;
};
protected:
struct NoInit {};
inline BasicMaterial(MaterialPass& material, NoInit);
struct BasicOptionIndexes
{
std::size_t alphaTest;
std::size_t hasAlphaMap;
std::size_t hasBaseColorMap;
};
struct BasicTextureIndexes
{
std::size_t alpha;
std::size_t baseColor;
};
struct BasicBuildOptions
{
// Common
std::vector<UInt8> defaultValues;
std::size_t* uniformBlockIndex = nullptr;
std::vector<std::shared_ptr<UberShader>> shaders;
// Basic
BasicUniformOffsets basicOffsets;
BasicOptionIndexes* basicOptionIndexes = nullptr;
BasicTextureIndexes* basicTextureIndexes = nullptr;
};
inline MaterialPass& GetMaterial();
inline const MaterialPass& GetMaterial() const;
static MaterialSettings::Builder Build(BasicBuildOptions& options);
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
static std::pair<BasicUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
std::size_t m_uniformBlockIndex;
BasicOptionIndexes m_basicOptionIndexes;
BasicTextureIndexes m_basicTextureIndexes;
BasicUniformOffsets m_basicUniformOffsets;
static std::shared_ptr<MaterialSettings> s_basicMaterialSettings;
static std::size_t s_uniformBlockIndex;
static BasicOptionIndexes s_basicOptionIndexes;
static BasicTextureIndexes s_basicTextureIndexes;
static BasicUniformOffsets s_basicUniformOffsets;
private:
static bool Initialize();
static void Uninitialize();
MaterialPass& m_material;
};
}
#include <Nazara/Graphics/BasicMaterial.inl>
#endif // NAZARA_GRAPHICS_BASICMATERIAL_HPP

View File

@ -1,149 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline BasicMaterial::BasicMaterial(MaterialPass& material, NoInit) :
m_material(material)
{
}
/*!
* \brief Enable/Disable alpha test for this material
*
* When enabled, all objects using this material will be rendered using alpha testing,
* rejecting pixels if their alpha component is under a defined threshold.
* This allows some kind of transparency with a much cheaper cost as it doesn't prevent any optimization (as deferred rendering or batching).
*
* \param alphaTest Defines if this material will use alpha testing
*
* \remark Invalidates the pipeline
*
* \see IsAlphaTestEnabled
* \see SetAlphaThreshold
*/
inline void BasicMaterial::EnableAlphaTest(bool alphaTest)
{
NazaraAssert(HasAlphaTest(), "Material has no alpha test option");
m_material.SetOptionValue(m_basicOptionIndexes.alphaTest, alphaTest);
}
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
return m_material.GetTexture(m_basicTextureIndexes.alpha);
}
inline const TextureSamplerInfo& BasicMaterial::GetAlphaSampler() const
{
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
return m_material.GetTextureSampler(m_basicTextureIndexes.alpha);
}
inline const std::shared_ptr<Texture>& BasicMaterial::GetBaseColorMap() const
{
NazaraAssert(HasBaseColorMap(), "Material has no alpha texture slot");
return m_material.GetTexture(m_basicTextureIndexes.baseColor);
}
inline const TextureSamplerInfo& BasicMaterial::GetBaseColorSampler() const
{
NazaraAssert(HasBaseColorMap(), "Material has no alpha texture slot");
return m_material.GetTextureSampler(m_basicTextureIndexes.baseColor);
}
inline bool BasicMaterial::IsAlphaTestEnabled() const
{
NazaraAssert(HasAlphaTest(), "Material has no alpha test option");
const auto& optionOpt = m_material.GetOptionValue(m_basicOptionIndexes.alphaTest);
if (std::holds_alternative<nzsl::Ast::NoValue>(optionOpt))
return false;
return std::get<bool>(optionOpt);
}
inline bool BasicMaterial::HasAlphaMap() const
{
return m_basicTextureIndexes.alpha != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasAlphaTest() const
{
return m_basicOptionIndexes.alphaTest != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasAlphaTestThreshold() const
{
return m_basicUniformOffsets.alphaThreshold != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasBaseColor() const
{
return m_basicUniformOffsets.baseColor != MaterialSettings::InvalidIndex;
}
inline bool BasicMaterial::HasBaseColorMap() const
{
return m_basicTextureIndexes.baseColor != MaterialSettings::InvalidIndex;
}
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
bool hasAlphaMap = (alphaMap != nullptr);
m_material.SetTexture(m_basicTextureIndexes.alpha, std::move(alphaMap));
if (m_basicOptionIndexes.hasBaseColorMap != MaterialSettings::InvalidIndex)
m_material.SetOptionValue(m_basicOptionIndexes.hasAlphaMap, hasAlphaMap);
}
inline void BasicMaterial::SetAlphaSampler(TextureSamplerInfo alphaSampler)
{
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
m_material.SetTextureSampler(m_basicTextureIndexes.alpha, std::move(alphaSampler));
}
inline void BasicMaterial::SetBaseColorMap(std::shared_ptr<Texture> baseColorMap)
{
NazaraAssert(HasBaseColorMap(), "Material has no diffuse map slot");
bool hasBaseColorMap = (baseColorMap != nullptr);
m_material.SetTexture(m_basicTextureIndexes.baseColor, std::move(baseColorMap));
if (m_basicOptionIndexes.hasBaseColorMap != MaterialSettings::InvalidIndex)
m_material.SetOptionValue(m_basicOptionIndexes.hasBaseColorMap, hasBaseColorMap);
}
inline void BasicMaterial::SetBaseColorSampler(TextureSamplerInfo diffuseSampler)
{
NazaraAssert(HasBaseColorMap(), "Material has no diffuse map slot");
m_material.SetTextureSampler(m_basicTextureIndexes.baseColor, std::move(diffuseSampler));
}
inline MaterialPass& BasicMaterial::GetMaterial()
{
return m_material;
}
inline const MaterialPass& BasicMaterial::GetMaterial() const
{
return m_material;
}
inline const std::shared_ptr<MaterialSettings>& BasicMaterial::GetSettings()
{
return s_basicMaterialSettings;
}
inline auto BasicMaterial::GetOffsets() -> const BasicUniformOffsets&
{
return s_basicUniformOffsets;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -1,38 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_DEPTHMATERIAL_HPP
#define NAZARA_GRAPHICS_DEPTHMATERIAL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
namespace Nz
{
class NAZARA_GRAPHICS_API DepthMaterial : public BasicMaterial
{
friend class MaterialPipeline;
public:
using BasicMaterial::BasicMaterial;
~DepthMaterial() = default;
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
protected:
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
private:
static bool Initialize();
static void Uninitialize();
static std::shared_ptr<MaterialSettings> s_depthMaterialSettings;
};
}
#include <Nazara/Graphics/DepthMaterial.inl>
#endif // NAZARA_GRAPHICS_DEPTHMATERIAL_HPP

View File

@ -11,6 +11,7 @@
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
@ -24,7 +25,6 @@ namespace Nz
class ElementRendererRegistry;
class FrameGraph;
class FramePipeline;
class Material;
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
{
@ -32,17 +32,17 @@ namespace Nz
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
DepthPipelinePass(const DepthPipelinePass&) = delete;
DepthPipelinePass(DepthPipelinePass&&) = delete;
~DepthPipelinePass();
~DepthPipelinePass() = default;
inline void InvalidateCommandBuffers();
inline void InvalidateElements();
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, std::size_t visibilityHash);
void RegisterMaterial(const Material& material);
void RegisterMaterialInstance(const MaterialInstance& materialInstance);
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t depthBufferIndex);
void UnregisterMaterial(const Material& material);
void UnregisterMaterialInstance(const MaterialInstance& materialInstance);
DepthPipelinePass& operator=(const DepthPipelinePass&) = delete;
DepthPipelinePass& operator=(DepthPipelinePass&&) = delete;
@ -52,8 +52,8 @@ namespace Nz
{
std::size_t usedCount = 1;
NazaraSlot(MaterialPass, OnMaterialPassPipelineInvalidated, onMaterialPipelineInvalidated);
NazaraSlot(MaterialPass, OnMaterialPassShaderBindingInvalidated, onMaterialShaderBindingInvalidated);
NazaraSlot(MaterialInstance, OnMaterialInstancePipelineInvalidated, onMaterialInstancePipelineInvalidated);
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
};
std::size_t m_depthPassIndex;
@ -61,7 +61,7 @@ namespace Nz
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
RenderQueue<const RenderElement*> m_renderQueue;
RenderQueueRegistry m_renderQueueRegistry;
AbstractViewer* m_viewer;

View File

@ -41,6 +41,27 @@ namespace Nz
Volume
};
enum class MaterialPropertyType
{
Bool,
Bool2,
Bool3,
Bool4,
Color,
Float,
Float2,
Float3,
Float4,
Int,
Int2,
Int3,
Int4,
UInt,
UInt2,
UInt3,
UInt4
};
enum class MaterialLightingType
{
None,
@ -69,7 +90,7 @@ namespace Nz
Perspective
};
enum class PredefinedShaderBinding
enum class EngineShaderBinding
{
InstanceDataUbo,
LightDataUbo,
@ -80,7 +101,7 @@ namespace Nz
Max = ViewerDataUbo
};
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(PredefinedShaderBinding::Max) + 1;
constexpr std::size_t PredefinedShaderBindingCount = static_cast<std::size_t>(EngineShaderBinding::Max) + 1;
}
#endif // NAZARA_GRAPHICS_ENUMS_HPP

View File

@ -21,6 +21,7 @@
#include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderQueue.hpp>
#include <Nazara/Graphics/RenderQueueRegistry.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utils/MemoryPool.hpp>
#include <memory>
@ -42,12 +43,7 @@ namespace Nz
ForwardFramePipeline(ForwardFramePipeline&&) = delete;
~ForwardFramePipeline();
void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) override;
void InvalidateViewer(std::size_t viewerIndex) override;
void InvalidateWorldInstance(std::size_t renderableIndex) override;
std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) override;
void RegisterMaterialPass(MaterialPass* materialPass) override;
std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) override;
std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) override;
std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) override;
@ -56,7 +52,6 @@ namespace Nz
void Render(RenderFrame& renderFrame) override;
void UnregisterLight(std::size_t lightIndex) override;
void UnregisterMaterialPass(MaterialPass* material) override;
void UnregisterRenderable(std::size_t renderableIndex) override;
void UnregisterSkeleton(std::size_t skeletonIndex) override;
void UnregisterViewer(std::size_t viewerIndex) override;
@ -73,6 +68,9 @@ namespace Nz
private:
BakedFrameGraph BuildFrameGraph();
void RegisterMaterialInstance(MaterialInstance* materialPass);
void UnregisterMaterialInstance(MaterialInstance* material);
struct ViewerData;
struct LightData
@ -83,11 +81,11 @@ namespace Nz
NazaraSlot(Light, OnLightDataInvalided, onLightInvalidated);
};
struct MaterialPassData
struct MaterialInstanceData
{
std::size_t usedCount = 0;
NazaraSlot(MaterialPass, OnMaterialPassInvalidated, onMaterialPassInvalided);
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
};
struct RenderableData
@ -109,6 +107,13 @@ namespace Nz
ShaderBindingPtr blitShaderBinding;
};
struct SkeletonInstanceData
{
SkeletonInstancePtr skeleton;
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
};
struct ViewerData
{
std::size_t forwardColorAttachment;
@ -122,27 +127,33 @@ namespace Nz
RenderQueueRegistry forwardRegistry;
RenderQueue<RenderElement*> forwardRenderQueue;
ShaderBindingPtr blitShaderBinding;
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
};
struct WorldInstanceData
{
WorldInstancePtr worldInstance;
NazaraSlot(TransferInterface, OnTransferRequired, onTransferRequired);
};
std::unordered_map<MaterialPass*, MaterialPassData> m_activeMaterialPasses;
std::unordered_map<const RenderTarget*, RenderTargetData> m_renderTargets;
std::unordered_set<MaterialPass*> m_invalidatedMaterialPasses;
std::unordered_map<MaterialInstance*, MaterialInstanceData> m_materialInstances;
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<FramePipelinePass::VisibleRenderable> m_visibleRenderables;
std::vector<const Light*> m_visibleLights;
robin_hood::unordered_set<TransferInterface*> m_transferSet;
BakedFrameGraph m_bakedFrameGraph;
Bitset<UInt64> m_invalidatedSkeletonInstances;
Bitset<UInt64> m_invalidatedViewerInstances;
Bitset<UInt64> m_invalidatedWorldInstances;
Bitset<UInt64> m_removedSkeletonInstances;
Bitset<UInt64> m_removedViewerInstances;
Bitset<UInt64> m_removedWorldInstances;
ElementRendererRegistry& m_elementRegistry;
MemoryPool<RenderableData> m_renderablePool;
MemoryPool<LightData> m_lightPool;
MemoryPool<SkeletonInstancePtr> m_skeletonInstances;
MemoryPool<SkeletonInstanceData> m_skeletonInstances;
MemoryPool<ViewerData> m_viewerPool;
MemoryPool<WorldInstancePtr> m_worldInstances;
MemoryPool<WorldInstanceData> m_worldInstances;
RenderFrame* m_currentRenderFrame;
bool m_rebuildFrameGraph;
};

View File

@ -12,6 +12,7 @@
#include <Nazara/Graphics/ElementRenderer.hpp>
#include <Nazara/Graphics/FramePipelinePass.hpp>
#include <Nazara/Graphics/Light.hpp>
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/RenderElement.hpp>
#include <Nazara/Graphics/RenderElementOwner.hpp>
@ -27,7 +28,6 @@ namespace Nz
class FrameGraph;
class FramePipeline;
class Light;
class Material;
class NAZARA_GRAPHICS_API ForwardPipelinePass : public FramePipelinePass
{
@ -35,17 +35,17 @@ namespace Nz
ForwardPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
ForwardPipelinePass(const ForwardPipelinePass&) = delete;
ForwardPipelinePass(ForwardPipelinePass&&) = delete;
~ForwardPipelinePass();
~ForwardPipelinePass() = default;
inline void InvalidateCommandBuffers();
inline void InvalidateElements();
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<const Light*>& visibleLights, std::size_t visibilityHash);
void RegisterMaterial(const Material& material);
void RegisterMaterialInstance(const MaterialInstance& material);
void RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
void UnregisterMaterial(const Material& material);
void UnregisterMaterialInstance(const MaterialInstance& material);
ForwardPipelinePass& operator=(const ForwardPipelinePass&) = delete;
ForwardPipelinePass& operator=(ForwardPipelinePass&&) = delete;
@ -57,8 +57,8 @@ namespace Nz
{
std::size_t usedCount = 1;
NazaraSlot(MaterialPass, OnMaterialPassPipelineInvalidated, onMaterialPipelineInvalidated);
NazaraSlot(MaterialPass, OnMaterialPassShaderBindingInvalidated, onMaterialShaderBindingInvalidated);
NazaraSlot(MaterialInstance, OnMaterialInstancePipelineInvalidated, onMaterialInstancePipelineInvalidated);
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
};
using LightKey = std::array<const Light*, MaxLightCountPerDraw>;
@ -86,7 +86,7 @@ namespace Nz
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<MaterialPass*, MaterialPassEntry> m_materialPasses;
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
std::unordered_map<const RenderElement*, RenderBufferView> m_lightPerRenderElement;
std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights;
std::vector<LightDataUbo> m_lightDataBuffers;

View File

@ -21,7 +21,6 @@ namespace Nz
class AbstractViewer;
class InstancedRenderable;
class Light;
class MaterialPass;
class RenderFrame;
class NAZARA_GRAPHICS_API FramePipeline
@ -34,12 +33,7 @@ namespace Nz
inline DebugDrawer& GetDebugDrawer();
virtual void InvalidateSkeletalInstance(std::size_t skeletalInstanceIndex) = 0;
virtual void InvalidateViewer(std::size_t viewerIndex) = 0;
virtual void InvalidateWorldInstance(std::size_t worldInstance) = 0;
virtual std::size_t RegisterLight(std::shared_ptr<Light> light, UInt32 renderMask) = 0;
virtual void RegisterMaterialPass(MaterialPass* materialPass) = 0;
virtual std::size_t RegisterRenderable(std::size_t worldInstanceIndex, std::size_t skeletonInstanceIndex, const InstancedRenderable* instancedRenderable, UInt32 renderMask, const Recti& scissorBox) = 0;
virtual std::size_t RegisterSkeleton(SkeletonInstancePtr skeletonInstance) = 0;
virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) = 0;
@ -48,7 +42,6 @@ namespace Nz
virtual void Render(RenderFrame& renderFrame) = 0;
virtual void UnregisterLight(std::size_t lightIndex) = 0;
virtual void UnregisterMaterialPass(MaterialPass* materialPass) = 0;
virtual void UnregisterRenderable(std::size_t renderableIndex) = 0;
virtual void UnregisterSkeleton(std::size_t skeletonIndex) = 0;
virtual void UnregisterViewer(std::size_t viewerIndex) = 0;

View File

@ -10,6 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <Nazara/Graphics/MaterialPassRegistry.hpp>
#include <Nazara/Graphics/TextureSamplerCache.hpp>
#include <Nazara/Renderer/RenderDevice.hpp>
@ -43,8 +44,10 @@ namespace Nz
inline const DefaultTextures& GetDefaultTextures() const;
inline MaterialPassRegistry& GetMaterialPassRegistry();
inline const MaterialPassRegistry& GetMaterialPassRegistry() const;
MaterialLoader& GetMaterialLoader();
const MaterialLoader& GetMaterialLoader() const;
inline MaterialInstanceLoader& GetMaterialInstanceLoader();
inline const MaterialInstanceLoader& GetMaterialInstanceLoader() const;
inline MaterialLoader& GetMaterialLoader();
inline const MaterialLoader& GetMaterialLoader() const;
inline PixelFormat GetPreferredDepthStencilFormat() const;
inline const std::shared_ptr<RenderDevice>& GetRenderDevice() const;
inline const RenderPassCache& GetRenderPassCache() const;
@ -59,8 +62,13 @@ namespace Nz
struct DefaultMaterials
{
std::shared_ptr<Material> depthMaterial;
std::shared_ptr<Material> noDepthMaterial;
std::shared_ptr<Material> basicMaterial;
std::shared_ptr<Material> phongMaterial;
std::shared_ptr<Material> pbrMaterial;
std::shared_ptr<MaterialInstance> basicDefault;
std::shared_ptr<MaterialInstance> basicNoDepth;
std::shared_ptr<MaterialInstance> basicTransparent;
};
struct DefaultTextures
@ -86,6 +94,7 @@ namespace Nz
std::shared_ptr<RenderPipelineLayout> m_blitPipelineLayout;
DefaultMaterials m_defaultMaterials;
DefaultTextures m_defaultTextures;
MaterialInstanceLoader m_materialInstanceLoader;
MaterialLoader m_materialLoader;
MaterialPassRegistry m_materialPassRegistry;
PixelFormat m_preferredDepthStencilFormat;

View File

@ -37,6 +37,16 @@ namespace Nz
return m_materialPassRegistry;
}
inline MaterialInstanceLoader& Graphics::GetMaterialInstanceLoader()
{
return m_materialInstanceLoader;
}
inline const MaterialInstanceLoader& Graphics::GetMaterialInstanceLoader() const
{
return m_materialInstanceLoader;
}
inline MaterialLoader& Graphics::GetMaterialLoader()
{
return m_materialLoader;

View File

@ -18,7 +18,7 @@ namespace Nz
{
class CommandBufferBuilder;
class ElementRendererRegistry;
class Material;
class MaterialInstance;
class RenderElement;
class SkeletonInstance;
class WorldInstance;
@ -36,7 +36,7 @@ namespace Nz
virtual void BuildElement(ElementRendererRegistry& registry, const ElementData& elementData, std::size_t passIndex, std::vector<RenderElementOwner>& elements) const = 0;
inline const Boxf& GetAABB() const;
virtual const std::shared_ptr<Material>& GetMaterial(std::size_t i) const = 0;
virtual const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i) const = 0;
virtual std::size_t GetMaterialCount() const = 0;
inline int GetRenderLayer() const;
@ -47,7 +47,7 @@ namespace Nz
NazaraSignal(OnAABBUpdate, InstancedRenderable* /*instancedRenderable*/, const Boxf& /*aabb*/);
NazaraSignal(OnElementInvalidated, InstancedRenderable* /*instancedRenderable*/);
NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<Material>& /*newMaterial*/);
NazaraSignal(OnMaterialInvalidated, InstancedRenderable* /*instancedRenderable*/, std::size_t /*materialIndex*/, const std::shared_ptr<MaterialInstance>& /*newMaterial*/);
struct ElementData
{

View File

@ -23,7 +23,7 @@ namespace Nz
enum class Orientation;
struct Section;
LinearSlicedSprite(std::shared_ptr<Material> material, Orientation orientation);
LinearSlicedSprite(std::shared_ptr<MaterialInstance> material, Orientation orientation);
LinearSlicedSprite(const LinearSlicedSprite&) = delete;
LinearSlicedSprite(LinearSlicedSprite&&) noexcept = default;
~LinearSlicedSprite() = default;
@ -35,7 +35,7 @@ namespace Nz
inline void Clear();
inline const Color& GetColor() const;
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override;
inline Orientation GetOrientation() const;
inline const Section& GetSection(std::size_t sectionIndex) const;
@ -46,7 +46,7 @@ namespace Nz
inline void RemoveSection(std::size_t sectionIndex);
inline void SetColor(const Color& color);
inline void SetMaterial(std::shared_ptr<Material> material);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetSection(std::size_t sectionIndex, float size, float textureCoord);
inline void SetSectionSize(std::size_t sectionIndex, float size);
inline void SetSectionTextureCoord(std::size_t sectionIndex, float textureCoord);
@ -76,7 +76,7 @@ namespace Nz
std::array<Section, MaxSection> m_sections;
std::array<VertexStruct_XYZ_Color_UV, 4 * MaxSection> m_vertices;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_material;
std::size_t m_sectionCount;
std::size_t m_spriteCount;
Color m_color;

View File

@ -71,7 +71,7 @@ namespace Nz
UpdateVertices();
}
inline void LinearSlicedSprite::SetMaterial(std::shared_ptr<Material> material)
inline void LinearSlicedSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
{
assert(material);

View File

@ -14,50 +14,91 @@
#include <Nazara/Core/ResourceSaver.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Graphics/RenderBufferPool.hpp>
#include <Nazara/Graphics/ShaderReflection.hpp>
#include <NZSL/Ast/Module.hpp>
#include <array>
#include <memory>
#include <unordered_map>
namespace Nz
{
struct NAZARA_GRAPHICS_API MaterialParams : ResourceParameters
{
MaterialLightingType lightingType = MaterialLightingType::None;
bool IsValid() const;
};
class Material;
class MaterialPass;
class MaterialInstance;
class RenderPipelineLayout;
using MaterialLibrary = ObjectLibrary<Material>;
using MaterialLoader = ResourceLoader<Material, MaterialParams>;
using MaterialManager = ResourceManager<Material, MaterialParams>;
using MaterialSaver = ResourceSaver<Material, MaterialParams>;
class NAZARA_GRAPHICS_API Material : public Resource
class NAZARA_GRAPHICS_API Material : public Resource, public std::enable_shared_from_this<Material>
{
public:
Material() = default;
struct TextureData;
struct UniformBlockData;
Material(MaterialSettings settings, const std::string& referenceModuleName);
Material(MaterialSettings settings, const nzsl::Ast::ModulePtr& referenceModule);
~Material() = default;
inline void AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass);
void AddPass(std::string passName, std::shared_ptr<MaterialPass> pass);
std::shared_ptr<MaterialInstance> CreateInstance() const;
const std::shared_ptr<MaterialPass>& FindPass(const std::string& passName) const;
std::shared_ptr<MaterialInstance> GetDefaultInstance() const;
template<typename F> void ForEachPass(F&& callback);
inline std::size_t FindTextureByTag(const std::string& tag) const;
inline std::size_t FindUniformBlockByTag(const std::string& tag) const;
inline const std::shared_ptr<MaterialPass>& GetPass(std::size_t passIndex) const;
inline bool HasPass(std::size_t passIndex) const;
inline void RemovePass(std::size_t passIndex);
void RemovePass(const std::string& passName);
inline UInt32 GetEngineBindingIndex(EngineShaderBinding shaderBinding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const MaterialSettings& GetSettings() const;
inline const TextureData& GetTextureData(std::size_t textureIndex) const;
inline std::size_t GetTextureCount() const;
inline const UniformBlockData& GetUniformBlockData(std::size_t uniformBlockIndex) const;
inline std::size_t GetUniformBlockCount() const;
static std::shared_ptr<Material> Build(const ParameterList& materialData);
static std::shared_ptr<Material> LoadFromFile(const std::filesystem::path& filePath, const MaterialParams& params = MaterialParams());
static std::shared_ptr<Material> LoadFromMemory(const void* data, std::size_t size, const MaterialParams& params = MaterialParams());
static std::shared_ptr<Material> LoadFromStream(Stream& stream, const MaterialParams& params = MaterialParams());
static inline ImageType ToImageType(nzsl::ImageType imageType);
static constexpr UInt32 InvalidBindingIndex = std::numeric_limits<UInt32>::max();
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
struct TextureData
{
UInt32 bindingSet;
UInt32 bindingIndex;
ImageType imageType;
};
struct UniformBlockData
{
UInt32 bindingSet;
UInt32 bindingIndex;
std::size_t structIndex;
std::unique_ptr<RenderBufferPool> bufferPool;
};
private:
std::vector<std::shared_ptr<MaterialPass>> m_passes;
std::array<UInt32, PredefinedShaderBindingCount> m_engineShaderBindings;
std::shared_ptr<RenderPipelineLayout> m_renderPipelineLayout;
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> m_optionValues;
std::unordered_map<std::string /*tag*/, std::size_t> m_textureByTag;
std::unordered_map<std::string /*tag*/, std::size_t> m_uniformBlockByTag;
std::vector<TextureData> m_textures;
std::vector<UniformBlockData> m_uniformBlocks;
mutable std::weak_ptr<MaterialInstance> m_defaultInstance;
MaterialSettings m_settings;
ShaderReflection m_reflection;
};
}

View File

@ -7,49 +7,75 @@
namespace Nz
{
inline void Material::AddPass(std::size_t passIndex, std::shared_ptr<MaterialPass> pass)
inline std::size_t Material::FindTextureByTag(const std::string& tag) const
{
if (passIndex >= m_passes.size())
m_passes.resize(passIndex + 1);
auto it = m_textureByTag.find(tag);
if (it == m_textureByTag.end())
return InvalidIndex;
m_passes[passIndex] = std::move(pass);
return it->second;
}
template<typename F>
void Material::ForEachPass(F&& callback)
inline std::size_t Material::FindUniformBlockByTag(const std::string& tag) const
{
for (std::size_t i = 0; i < m_passes.size(); ++i)
{
if (m_passes[i])
callback(i, m_passes[i]);
}
auto it = m_uniformBlockByTag.find(tag);
if (it == m_uniformBlockByTag.end())
return InvalidIndex;
return it->second;
}
inline const std::shared_ptr<MaterialPass>& Material::GetPass(std::size_t passIndex) const
inline UInt32 Material::GetEngineBindingIndex(EngineShaderBinding shaderBinding) const
{
if (passIndex >= m_passes.size())
return m_engineShaderBindings[UnderlyingCast(shaderBinding)];
}
inline const std::shared_ptr<RenderPipelineLayout>& Material::GetRenderPipelineLayout() const
{
return m_renderPipelineLayout;
}
inline const MaterialSettings& Material::GetSettings() const
{
return m_settings;
}
inline auto Material::GetTextureData(std::size_t textureIndex) const -> const TextureData&
{
assert(textureIndex < m_textures.size());
return m_textures[textureIndex];
}
inline std::size_t Material::GetTextureCount() const
{
return m_textures.size();
}
inline auto Material::GetUniformBlockData(std::size_t uniformBlockIndex) const -> const UniformBlockData&
{
assert(uniformBlockIndex < m_uniformBlocks.size());
return m_uniformBlocks[uniformBlockIndex];
}
inline std::size_t Material::GetUniformBlockCount() const
{
return m_uniformBlocks.size();
}
inline ImageType Material::ToImageType(nzsl::ImageType imageType)
{
switch (imageType)
{
static std::shared_ptr<MaterialPass> dummy;
return dummy;
case nzsl::ImageType::E1D: return ImageType::E1D;
case nzsl::ImageType::E1D_Array: return ImageType::E1D_Array;
case nzsl::ImageType::E2D: return ImageType::E2D;
case nzsl::ImageType::E2D_Array: return ImageType::E2D_Array;
case nzsl::ImageType::E3D: return ImageType::E3D;
case nzsl::ImageType::Cubemap: return ImageType::Cubemap;
}
return m_passes[passIndex];
}
inline bool Material::HasPass(std::size_t passIndex) const
{
if (passIndex >= m_passes.size())
return false;
return m_passes[passIndex] != nullptr;
}
inline void Material::RemovePass(std::size_t passIndex)
{
if (passIndex >= m_passes.size())
return;
m_passes[passIndex].reset();
NazaraError("invalid image type 0x" + NumberToString(UnderlyingCast(imageType), 16));
return ImageType::E2D;
}
}

View File

@ -0,0 +1,165 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_MATERIALINSTANCE_HPP
#define NAZARA_GRAPHICS_MATERIALINSTANCE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Renderer/RenderBufferView.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utils/FunctionRef.hpp>
#include <NZSL/Ast/ConstantValue.hpp>
#include <memory>
#include <unordered_map>
#include <vector>
namespace Nz
{
struct NAZARA_GRAPHICS_API MaterialInstanceParams : ResourceParameters
{
MaterialLightingType lightingType = MaterialLightingType::None;
bool IsValid() const;
};
class Material;
class MaterialInstance;
class MaterialPipeline;
class Texture;
using MaterialInstanceLibrary = ObjectLibrary<MaterialInstance>;
using MaterialInstanceLoader = ResourceLoader<MaterialInstance, MaterialInstanceParams>;
using MaterialInstanceManager = ResourceManager<MaterialInstance, MaterialInstanceParams>;
using MaterialInstanceSaver = ResourceSaver<MaterialInstance, MaterialInstanceParams>;
class NAZARA_GRAPHICS_API MaterialInstance : public TransferInterface
{
struct CopyToken {};
public:
MaterialInstance(std::shared_ptr<const Material> parent);
MaterialInstance(const MaterialInstance&) = delete;
MaterialInstance(const MaterialInstance& material, CopyToken);
MaterialInstance(MaterialInstance&&) = delete;
~MaterialInstance();
inline std::shared_ptr<MaterialInstance> Clone() const;
void DisablePass(std::string_view passName);
inline void DisablePass(std::size_t passIndex);
void EnablePass(std::string_view passName, bool enable = true);
inline void EnablePass(std::size_t passIndex, bool enable = true);
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
inline std::size_t FindTextureProperty(std::string_view propertyName) const;
inline std::size_t FindValueProperty(std::string_view propertyName) const;
inline const std::shared_ptr<const Material>& GetParentMaterial() const;
inline MaterialPassFlags GetPassFlags(std::size_t passIndex) const;
const std::shared_ptr<MaterialPipeline>& GetPipeline(std::size_t passIndex) const;
inline const std::shared_ptr<Texture>* GetTextureProperty(std::string_view propertyName) const;
inline const std::shared_ptr<Texture>& GetTextureProperty(std::size_t textureIndex) const;
inline const std::shared_ptr<Texture>& GetTexturePropertyOverride(std::size_t textureIndex) const;
inline const TextureSamplerInfo* GetTextureSamplerProperty(std::string_view propertyName) const;
inline const TextureSamplerInfo& GetTextureSamplerProperty(std::size_t textureIndex) const;
inline const MaterialSettings::Value* GetValueProperty(std::string_view propertyName) const;
inline const MaterialSettings::Value& GetValueProperty(std::size_t valueIndex) const;
inline const MaterialSettings::Value& GetValuePropertyOverride(std::size_t valueIndex) const;
bool HasPass(std::string_view passName) const;
inline bool HasPass(std::size_t passIndex) const;
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
inline void SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture);
inline void SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo);
void SetTextureProperty(std::size_t textureIndex, std::shared_ptr<Texture> texture);
void SetTextureProperty(std::size_t textureIndex, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo);
inline void SetTextureSamplerProperty(std::string_view propertyName, const TextureSamplerInfo& samplerInfo);
void SetTextureSamplerProperty(std::size_t textureIndex, const TextureSamplerInfo& samplerInfo);
inline void SetValueProperty(std::string_view propertyName, const MaterialSettings::Value& value);
void SetValueProperty(std::size_t valueIndex, const MaterialSettings::Value& value);
void UpdateOptionValue(UInt32 optionHash, const nzsl::Ast::ConstantSingleValue& value);
void UpdatePassFlags(std::string_view passName, MaterialPassFlags materialFlags);
inline void UpdatePassFlags(std::size_t passName, MaterialPassFlags materialFlags);
void UpdatePassStates(std::string_view passName, FunctionRef<bool(RenderStates&)> stateUpdater);
template<typename F> void UpdatePassStates(std::size_t passIndex, F&& stateUpdater);
void UpdateTextureBinding(std::size_t textureBinding, std::shared_ptr<Texture> texture, std::shared_ptr<TextureSampler> textureSampler);
void UpdateUniformBufferData(std::size_t uniformBufferIndex, std::size_t offset, std::size_t size, const void* data);
MaterialInstance& operator=(const MaterialInstance&) = delete;
MaterialInstance& operator=(MaterialInstance&&) = delete;
static constexpr std::size_t InvalidPropertyIndex = MaterialSettings::InvalidPropertyIndex;
NazaraSignal(OnMaterialInstancePipelineInvalidated, const MaterialInstance* /*matInstance*/, std::size_t /*passIndex*/);
NazaraSignal(OnMaterialInstanceShaderBindingInvalidated, const MaterialInstance* /*matInstance*/);
private:
inline void InvalidatePassPipeline(std::size_t passIndex);
inline void InvalidateShaderBinding();
struct PassShader
{
std::shared_ptr<UberShader> shader;
NazaraSlot(UberShader, OnShaderUpdated, onShaderUpdated);
};
struct PassData
{
mutable MaterialPipelineInfo pipelineInfo;
mutable std::shared_ptr<MaterialPipeline> pipeline;
std::vector<PassShader> shaders;
MaterialPassFlags flags;
bool enabled = false;
};
struct TextureBinding
{
std::shared_ptr<Texture> texture;
std::shared_ptr<TextureSampler> sampler;
};
struct TextureProperty
{
std::shared_ptr<Texture> texture;
TextureSamplerInfo samplerInfo;
};
struct UniformBuffer
{
std::size_t bufferIndex;
std::vector<UInt8> values;
RenderBufferView bufferView;
bool dataInvalidated = true;
};
std::shared_ptr<const Material> m_parent;
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> m_optionValuesOverride;
std::vector<MaterialSettings::Value> m_valueOverride;
std::vector<PassData> m_passes;
std::vector<TextureBinding> m_textureBinding;
std::vector<TextureProperty> m_textureOverride;
std::vector<UniformBuffer> m_uniformBuffers;
const MaterialSettings& m_materialSettings;
};
}
#include <Nazara/Graphics/MaterialInstance.inl>
#endif // NAZARA_GRAPHICS_MATERIALINSTANCE_HPP

View File

@ -0,0 +1,216 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/MaterialInstance.hpp>
#include <type_traits>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline std::shared_ptr<MaterialInstance> MaterialInstance::Clone() const
{
return std::make_shared<MaterialInstance>(*this, CopyToken{});
}
inline void MaterialInstance::DisablePass(std::size_t passIndex)
{
EnablePass(passIndex, false);
}
inline void MaterialInstance::EnablePass(std::size_t passIndex, bool enable)
{
assert(passIndex < m_passes.size());
if (m_passes[passIndex].enabled != enable)
{
m_passes[passIndex].enabled = enable;
InvalidatePassPipeline(passIndex);
}
}
inline std::size_t MaterialInstance::FindTextureProperty(std::string_view propertyName) const
{
return m_materialSettings.FindTextureProperty(propertyName);
}
inline std::size_t MaterialInstance::FindValueProperty(std::string_view propertyName) const
{
return m_materialSettings.FindValueProperty(propertyName);
}
inline const std::shared_ptr<const Material>& MaterialInstance::GetParentMaterial() const
{
return m_parent;
}
inline MaterialPassFlags MaterialInstance::GetPassFlags(std::size_t passIndex) const
{
assert(passIndex < m_passes.size());
return m_passes[passIndex].flags;
}
inline const std::shared_ptr<Texture>* MaterialInstance::GetTextureProperty(std::string_view propertyName) const
{
std::size_t propertyIndex = FindTextureProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no texture property named " + std::string(propertyName));
return nullptr;
}
return &GetTextureProperty(propertyIndex);
}
inline const std::shared_ptr<Texture>& MaterialInstance::GetTextureProperty(std::size_t textureIndex) const
{
if (const std::shared_ptr<Texture>& textureOverride = GetTexturePropertyOverride(textureIndex))
return textureOverride;
else
return m_materialSettings.GetTextureProperty(textureIndex).defaultTexture;
}
inline const std::shared_ptr<Texture>& MaterialInstance::GetTexturePropertyOverride(std::size_t textureIndex) const
{
assert(textureIndex < m_textureOverride.size());
return m_textureOverride[textureIndex].texture;
}
inline const TextureSamplerInfo* MaterialInstance::GetTextureSamplerProperty(std::string_view propertyName) const
{
std::size_t propertyIndex = FindTextureProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no texture property named " + std::string(propertyName));
return nullptr;
}
return &GetTextureSamplerProperty(propertyIndex);
}
inline const TextureSamplerInfo& MaterialInstance::GetTextureSamplerProperty(std::size_t textureIndex) const
{
assert(textureIndex < m_textureOverride.size());
return m_textureOverride[textureIndex].samplerInfo;
}
inline const MaterialSettings::Value* MaterialInstance::GetValueProperty(std::string_view propertyName) const
{
std::size_t propertyIndex = FindValueProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no value property named " + std::string(propertyName));
return nullptr;
}
return &GetValueProperty(propertyIndex);
}
inline const MaterialSettings::Value& MaterialInstance::GetValueProperty(std::size_t valueIndex) const
{
if (const MaterialSettings::Value& valueOverride = GetValuePropertyOverride(valueIndex); !std::holds_alternative<MaterialPropertyNoValue>(valueOverride))
return valueOverride;
else
return m_materialSettings.GetValueProperty(valueIndex).defaultValue;
}
inline const MaterialSettings::Value& MaterialInstance::GetValuePropertyOverride(std::size_t valueIndex) const
{
assert(valueIndex < m_valueOverride.size());
return m_valueOverride[valueIndex];
}
inline bool MaterialInstance::HasPass(std::size_t passIndex) const
{
return passIndex < m_passes.size() && m_passes[passIndex].enabled;
}
inline void MaterialInstance::SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture)
{
std::size_t propertyIndex = FindTextureProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no texture property named " + std::string(propertyName));
return;
}
return SetTextureProperty(propertyIndex, std::move(texture));
}
inline void MaterialInstance::SetTextureProperty(std::string_view propertyName, std::shared_ptr<Texture> texture, const TextureSamplerInfo& samplerInfo)
{
std::size_t propertyIndex = FindTextureProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no texture property named " + std::string(propertyName));
return;
}
return SetTextureProperty(propertyIndex, std::move(texture), samplerInfo);
}
inline void MaterialInstance::SetTextureSamplerProperty(std::string_view propertyName, const TextureSamplerInfo& samplerInfo)
{
std::size_t propertyIndex = FindTextureProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no texture property named " + std::string(propertyName));
return;
}
return SetTextureSamplerProperty(propertyIndex, samplerInfo);
}
inline void MaterialInstance::SetValueProperty(std::string_view propertyName, const MaterialSettings::Value& value)
{
std::size_t propertyIndex = FindValueProperty(propertyName);
if (propertyIndex == MaterialSettings::InvalidPropertyIndex)
{
NazaraError("material has no value property named " + std::string(propertyName));
return;
}
return SetValueProperty(propertyIndex, value);
}
inline void MaterialInstance::UpdatePassFlags(std::size_t passIndex, MaterialPassFlags materialFlags)
{
assert(passIndex < m_passes.size());
if (m_passes[passIndex].flags != materialFlags)
{
m_passes[passIndex].flags = materialFlags;
InvalidatePassPipeline(passIndex);
}
}
template<typename F>
void MaterialInstance::UpdatePassStates(std::size_t passIndex, F&& stateUpdater)
{
assert(passIndex < m_passes.size());
using Ret = std::invoke_result_t<F, RenderStates&>;
if constexpr (std::is_same_v<Ret, bool>)
{
if (!stateUpdater(static_cast<RenderStates&>(m_passes[passIndex].pipelineInfo)))
return;
}
else if constexpr (std::is_void_v<Ret>)
stateUpdater(static_cast<RenderStates&>(m_passes[passIndex].pipelineInfo));
else
static_assert(AlwaysFalse<Ret>(), "callback must either return a bool or nothing");
InvalidatePassPipeline(passIndex);
}
inline void MaterialInstance::InvalidatePassPipeline(std::size_t passIndex)
{
assert(passIndex < m_passes.size());
m_passes[passIndex].pipeline.reset();
OnMaterialInstancePipelineInvalidated(this, passIndex);
}
inline void MaterialInstance::InvalidateShaderBinding()
{
OnMaterialInstanceShaderBindingInvalidated(this);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -10,10 +10,6 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Core/ObjectLibrary.hpp>
#include <Nazara/Core/Resource.hpp>
#include <Nazara/Core/ResourceLoader.hpp>
#include <Nazara/Core/ResourceManager.hpp>
#include <Nazara/Core/ResourceParameters.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialPipeline.hpp>
@ -24,145 +20,19 @@
#include <Nazara/Utils/Signal.hpp>
#include <NZSL/Ast/ConstantValue.hpp>
#include <array>
#include <memory>
#include <string>
#include <vector>
namespace Nz
{
class CommandBufferBuilder;
class RenderFrame;
class NAZARA_GRAPHICS_API MaterialPass
struct MaterialPass
{
public:
MaterialPass(std::shared_ptr<const MaterialSettings> settings);
MaterialPass(const MaterialPass&) = delete;
MaterialPass(MaterialPass&&) = delete;
inline ~MaterialPass();
inline void Configure(std::shared_ptr<MaterialPipeline> pipeline);
inline void Configure(const MaterialPipelineInfo& pipelineInfo);
inline void EnableBlending(bool blending);
inline void EnableColorWrite(bool colorWrite);
inline void EnableDepthBuffer(bool depthBuffer);
inline void EnableDepthClamp(bool depthClamp);
inline void EnableDepthWrite(bool depthWrite);
inline void EnableFaceCulling(bool faceCulling);
inline void EnableFlag(MaterialPassFlag flag, bool enable = true);
inline void EnableScissorTest(bool scissorTest);
inline void EnableStencilTest(bool stencilTest);
inline void EnsurePipelineUpdate() const;
void FillShaderBinding(std::vector<ShaderBinding::Binding>& bindings) const;
inline RendererComparison GetDepthCompareFunc() const;
inline BlendEquation GetBlendAlphaModeEquation() const;
inline BlendEquation GetBlendColorModeEquation() const;
inline BlendFunc GetBlendDstAlphaFunc() const;
inline BlendFunc GetBlendDstColorFunc() const;
inline BlendFunc GetBlendSrcAlphaFunc() const;
inline BlendFunc GetBlendSrcColorFunc() const;
inline FaceSide GetFaceCulling() const;
inline FaceFilling GetFaceFilling() const;
inline MaterialPassFlags GetFlags() const;
inline float GetLineWidth() const;
inline const nzsl::Ast::ConstantSingleValue& GetOptionValue(std::size_t optionIndex) const;
inline const std::shared_ptr<MaterialPipeline>& GetPipeline() const;
inline const MaterialPipelineInfo& GetPipelineInfo() const;
inline float GetPointSize() const;
inline PrimitiveMode GetPrimitiveMode() const;
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
inline const std::shared_ptr<UberShader>& GetShader(nzsl::ShaderStageType shaderStage) const;
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
inline const TextureSamplerInfo& GetTextureSampler(std::size_t textureIndex) const;
inline const std::shared_ptr<RenderBuffer>& GetUniformBuffer(std::size_t bufferIndex) const;
inline const std::vector<UInt8>& GetUniformBufferConstData(std::size_t bufferIndex) const;
inline std::vector<UInt8>& GetUniformBufferData(std::size_t bufferIndex);
inline bool HasTexture(std::size_t textureIndex) const;
inline bool IsBlendingEnabled() const;
inline bool IsColorWriteEnabled() const;
inline bool IsDepthBufferEnabled() const;
inline bool IsDepthClampEnabled() const;
inline bool IsDepthWriteEnabled() const;
inline bool IsFaceCullingEnabled() const;
inline bool IsFlagEnabled(MaterialPassFlag flag) const;
inline bool IsScissorTestEnabled() const;
inline bool IsStencilTestEnabled() const;
inline void SetDepthCompareFunc(RendererComparison depthFunc);
inline void SetBlendEquation(BlendEquation colorMode, BlendEquation alphaMode);
inline void SetBlendFunc(BlendFunc srcColor, BlendFunc dstColor, BlendFunc srcAlpha, BlendFunc dstAlpha);
inline void SetFaceCulling(FaceSide faceSide);
inline void SetFaceFilling(FaceFilling filling);
inline void SetLineWidth(float lineWidth);
inline void SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantSingleValue value);
inline void SetPointSize(float pointSize);
inline void SetPrimitiveMode(PrimitiveMode mode);
inline void SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer);
inline void SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer, UInt64 offset, UInt64 size);
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
inline void SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo);
void Update(RenderFrame& renderFrame, CommandBufferBuilder& builder);
MaterialPass& operator=(const MaterialPass&) = delete;
MaterialPass& operator=(MaterialPass&&) = delete;
// Signals:
NazaraSignal(OnMaterialPassInvalidated, const MaterialPass* /*materialPass*/);
NazaraSignal(OnMaterialPassPipelineInvalidated, const MaterialPass* /*materialPass*/);
NazaraSignal(OnMaterialPassShaderBindingInvalidated, const MaterialPass* /*materialPass*/);
NazaraSignal(OnMaterialPassRelease, const MaterialPass* /*materialPass*/);
private:
inline void InvalidatePipeline();
inline void InvalidateShaderBinding();
inline void InvalidateTextureSampler(std::size_t textureIndex);
inline void InvalidateUniformData(std::size_t uniformBufferIndex);
void UpdatePipeline() const;
struct MaterialTexture
{
mutable std::shared_ptr<TextureSampler> sampler;
std::shared_ptr<Texture> texture;
TextureSamplerInfo samplerInfo;
};
struct ShaderEntry
{
NazaraSlot(UberShader, OnShaderUpdated, onShaderUpdated);
};
struct ShaderUniformBuffer
{
std::shared_ptr<RenderBuffer> buffer; //< kept for ownership
RenderBufferView bufferView;
};
struct UniformBuffer
{
std::shared_ptr<RenderBuffer> buffer;
std::vector<UInt8> data;
bool dataInvalidated = true;
};
std::array<nzsl::Ast::ConstantSingleValue, 64> m_optionValues;
std::shared_ptr<const MaterialSettings> m_settings;
std::vector<MaterialTexture> m_textures;
std::vector<ShaderEntry> m_shaders;
std::vector<ShaderUniformBuffer> m_sharedUniformBuffers;
std::vector<UniformBuffer> m_uniformBuffers;
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
mutable MaterialPipelineInfo m_pipelineInfo;
MaterialPassFlags m_flags;
mutable bool m_pipelineUpdated;
MaterialPassFlags flags;
RenderStates states;
std::unordered_map<UInt32, nzsl::Ast::ConstantSingleValue> options;
std::vector<std::shared_ptr<UberShader>> shaders;
};
}
#include <Nazara/Graphics/MaterialPass.inl>
#endif // NAZARA_GRAPHICS_MATERIALPASS_HPP

View File

@ -1,683 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
/*!
* \brief Destructs the object and calls OnMaterialRelease
*
* \see OnMaterialRelease
*/
inline MaterialPass::~MaterialPass()
{
OnMaterialPassRelease(this);
}
/*!
* \brief Reset material pipeline state
*
* Sets the material pipeline
*
* \remark pipeline must be valid
*
* \see Configure
*/
inline void MaterialPass::Configure(std::shared_ptr<MaterialPipeline> pipeline)
{
NazaraAssert(pipeline, "Invalid material pipeline");
m_pipeline = std::move(pipeline);
m_pipelineInfo = m_pipeline->GetInfo();
m_pipelineUpdated = true;
}
/*!
* \brief Reset material pipeline state
*
* Sets the material pipeline using pipeline info
*
* \remark pipeline must be valid
*
* \see Configure
*/
inline void MaterialPass::Configure(const MaterialPipelineInfo& pipelineInfo)
{
m_pipelineInfo = pipelineInfo;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable blending for this material
*
* When enabled, all objects using this material will be rendered using blending, obeying the dstBlend and srcBlend parameters
* This is useful with translucent objects, but will reduces performance as it prevents some optimizations (as deferred rendering)
*
* \param blending Defines if this material will use blending
*
* \remark Invalidates the pipeline
*
* \see IsBlendingEnabled
* \see SetDstBlend
* \see SetSrcBlend
*/
inline void MaterialPass::EnableBlending(bool blending)
{
m_pipelineInfo.blending = blending;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable color writing for this material
*
* \param colorWrite Defines if this material will use color writing
*
* \remark Invalidates the pipeline
*
* \see IsColorWritingEnabled
*/
inline void MaterialPass::EnableColorWrite(bool colorWrite)
{
m_pipelineInfo.colorWrite = colorWrite;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable depth buffer for this material
*
* When enabled, all objects using this material will be rendered using a depth buffer, if the RenderTarget has one.
* This will enable Depth Test, preventing further fragments to render on top of closer ones.
*
* This parameter is required for depth writing.
*
* In order to enable depth writing without enabling depth test, set the depth comparison function to RendererComparison::Never
*
* \param depthBuffer Defines if this material will use depth buffer
*
* \remark Invalidates the pipeline
*
* \see EnableDepthWrite
* \see IsDepthBufferEnabled
* \see SetDepthFunc
*/
inline void MaterialPass::EnableDepthBuffer(bool depthBuffer)
{
m_pipelineInfo.depthBuffer = depthBuffer;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable depth clamp for this material
*
* When enabled, all fragments generated by this material will be clamped to znear or zfar
* instead of being clipped out when outside this range.
*
* This can be useful to prevent clipping near or far primitives.
*
* \param depthClamp Defines if this material will use depth clamping
*
* \remark Invalidates the pipeline
* \remark Depth clamping requires RenderDeviceFeatures::depthClamping to be true
*
* \see IsDepthClampEnabled
*/
inline void MaterialPass::EnableDepthClamp(bool depthClamp)
{
m_pipelineInfo.depthClamp = depthClamp;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable depth writing for this material
*
* When enabled, and if depth buffer is enabled and present, all fragments generated with this material will write
* to the depth buffer if they pass depth test.
*
* This is usually disabled with translucent objects, as depth test is wanted to prevent them from rendering on top of opaque objects but
* not depth writing (which could make other translucent fragments to fail depth test)
*
* \param depthBuffer Defines if this material will use depth write
*
* \remark Invalidates the pipeline
*
* \see EnableDepthBuffer
* \see IsDepthWriteEnabled
*/
inline void MaterialPass::EnableDepthWrite(bool depthWrite)
{
m_pipelineInfo.depthWrite = depthWrite;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable face culling for this material
*
* When enabled, the material prevents front and/or back faces from rendering.
* This is commonly used as an optimization to prevent processing of hidden faces by the rendering device.
*
* Use SetFaceCulling to control which side will be eliminated.
*
* \param faceCulling Defines if this material will use face culling
*
* \remark Invalidates the pipeline
*
* \see IsFaceCullingEnabled
* \see SetFaceCulling
*/
inline void MaterialPass::EnableFaceCulling(bool faceCulling)
{
m_pipelineInfo.faceCulling = faceCulling;
InvalidatePipeline();
}
inline void MaterialPass::EnableFlag(MaterialPassFlag flag, bool enable)
{
if (enable)
m_flags |= flag;
else
m_flags &= ~flag;
}
/*!
* \brief Enable/Disable scissor test for this material
*
* When enabled, the material prevents fragments out of the scissor box to be rendered.
* This can be useful with GUI, where widgets must not be rendered outside of their parent rendering area.
*
* \param scissorTest Defines if this material will use scissor test
*
* \remark Invalidates the pipeline
*
* \see IsScissorTestEnabled
*/
inline void MaterialPass::EnableScissorTest(bool scissorTest)
{
m_pipelineInfo.scissorTest = scissorTest;
InvalidatePipeline();
}
/*!
* \brief Enable/Disable stencil test for this material
*
* When enabled, all fragments must pass the stencil test to be rendered.
*
* \param scissorTest Defines if this material will use stencil test
*
* \remark Invalidates the pipeline
*
* \see IsStencilTestEnabled
*/
inline void MaterialPass::EnableStencilTest(bool stencilTest)
{
m_pipelineInfo.stencilTest = stencilTest;
InvalidatePipeline();
}
/*!
* \brief Ensures the pipeline gets updated
*
* When the pipeline gets invalidated, it's not updated until required (per example by calling GetPipeline).
* Using this function forces the pipeline update, making GetPipeline thread-safe as long as the pipeline does not get invalidated.
*
* \see GetPipeline
*/
inline void MaterialPass::EnsurePipelineUpdate() const
{
if (!m_pipelineUpdated)
UpdatePipeline();
}
/*!
* \brief Gets the function to compare depth
*
* \return Function comparing the depth of two materials
*
* \see EnableDepthTest
* \see SetAmbientColor
*/
inline RendererComparison MaterialPass::GetDepthCompareFunc() const
{
return m_pipelineInfo.depthCompare;
}
inline BlendEquation MaterialPass::GetBlendAlphaModeEquation() const
{
return m_pipelineInfo.blend.modeAlpha;
}
inline BlendEquation MaterialPass::GetBlendColorModeEquation() const
{
return m_pipelineInfo.blend.modeColor;
}
inline BlendFunc MaterialPass::GetBlendDstAlphaFunc() const
{
return m_pipelineInfo.blend.dstAlpha;
}
inline BlendFunc MaterialPass::GetBlendDstColorFunc() const
{
return m_pipelineInfo.blend.dstColor;
}
inline BlendFunc MaterialPass::GetBlendSrcAlphaFunc() const
{
return m_pipelineInfo.blend.srcAlpha;
}
inline BlendFunc MaterialPass::GetBlendSrcColorFunc() const
{
return m_pipelineInfo.blend.srcColor;
}
/*!
* \brief Gets the face culling
*
* \return Current face culling side
*
* \see SetFaceCulling
*/
inline FaceSide MaterialPass::GetFaceCulling() const
{
return m_pipelineInfo.cullingSide;
}
/*!
* \brief Gets the face filling
* \return Current face filling
*/
inline FaceFilling MaterialPass::GetFaceFilling() const
{
return m_pipelineInfo.faceFilling;
}
inline MaterialPassFlags MaterialPass::GetFlags() const
{
return m_flags;
}
/*!
* \brief Gets the line width of this material
* \return Line width
*/
inline float MaterialPass::GetLineWidth() const
{
return m_pipelineInfo.lineWidth;
}
inline const nzsl::Ast::ConstantSingleValue& MaterialPass::GetOptionValue(std::size_t optionIndex) const
{
assert(optionIndex < m_optionValues.size());
return m_optionValues[optionIndex];
}
/*!
* \brief Gets the render states
* \return Constant reference to the render states
*/
inline const std::shared_ptr<MaterialPipeline>& MaterialPass::GetPipeline() const
{
EnsurePipelineUpdate();
return m_pipeline;
}
/*!
* \brief Gets the pipeline informations
* \return Constant reference to the pipeline info
*/
inline const MaterialPipelineInfo& MaterialPass::GetPipelineInfo() const
{
return m_pipelineInfo;
}
/*!
* \brief Gets the point size of this material
* \return Point size
*/
inline float MaterialPass::GetPointSize() const
{
return m_pipelineInfo.pointSize;
}
inline PrimitiveMode MaterialPass::GetPrimitiveMode() const
{
return m_pipelineInfo.primitiveMode;
}
inline const std::shared_ptr<const MaterialSettings>& MaterialPass::GetSettings() const
{
return m_settings;
}
/*!
* \brief Gets the über-shader used by this material
* \return Constant pointer to the über-shader used
*/
inline const std::shared_ptr<UberShader>& MaterialPass::GetShader(nzsl::ShaderStageType shaderStage) const
{
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
}
inline const std::shared_ptr<Texture>& MaterialPass::GetTexture(std::size_t textureIndex) const
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
return m_textures[textureIndex].texture;
}
inline const TextureSamplerInfo& MaterialPass::GetTextureSampler(std::size_t textureIndex) const
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
return m_textures[textureIndex].samplerInfo;
}
inline const std::shared_ptr<RenderBuffer>& MaterialPass::GetUniformBuffer(std::size_t bufferIndex) const
{
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
return m_uniformBuffers[bufferIndex].buffer;
}
inline const std::vector<UInt8>& MaterialPass::GetUniformBufferConstData(std::size_t bufferIndex) const
{
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
return m_uniformBuffers[bufferIndex].data;
}
inline std::vector<UInt8>& MaterialPass::GetUniformBufferData(std::size_t bufferIndex)
{
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid uniform buffer index");
UniformBuffer& uboEntry = m_uniformBuffers[bufferIndex];
InvalidateUniformData(bufferIndex);
return uboEntry.data;
}
inline bool MaterialPass::HasTexture(std::size_t textureIndex) const
{
return GetTexture(textureIndex) != nullptr;
}
/*!
* \brief Checks whether this material has blending enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsBlendingEnabled() const
{
return m_pipelineInfo.blending;
}
/*!
* \brief Checks whether this material has color write enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsColorWriteEnabled() const
{
return m_pipelineInfo.colorWrite;
}
/*!
* \brief Checks whether this material has depth buffer enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsDepthBufferEnabled() const
{
return m_pipelineInfo.depthBuffer;
}
/*!
* \brief Checks whether this material has depth clamping enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsDepthClampEnabled() const
{
return m_pipelineInfo.depthClamp;
}
/*!
* \brief Checks whether this material has depth writing enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsDepthWriteEnabled() const
{
return m_pipelineInfo.depthWrite;
}
/*!
* \brief Checks whether this material has face culling enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsFaceCullingEnabled() const
{
return m_pipelineInfo.faceCulling;
}
inline bool MaterialPass::IsFlagEnabled(MaterialPassFlag flag) const
{
return m_flags.Test(flag);
}
/*!
* \brief Checks whether this material has scissor test enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsScissorTestEnabled() const
{
return m_pipelineInfo.scissorTest;
}
/*!
* \brief Checks whether this material has stencil test enabled
* \return true If it is the case
*/
inline bool MaterialPass::IsStencilTestEnabled() const
{
return m_pipelineInfo.stencilTest;
}
/*!
* \brief Sets the depth functor
*
* \param depthFunc
*
* \remark Invalidates the pipeline
*/
inline void MaterialPass::SetDepthCompareFunc(RendererComparison depthFunc)
{
m_pipelineInfo.depthCompare = depthFunc;
InvalidatePipeline();
}
inline void MaterialPass::SetBlendEquation(BlendEquation colorMode, BlendEquation alphaMode)
{
m_pipelineInfo.blend.modeAlpha = alphaMode;
m_pipelineInfo.blend.modeColor = colorMode;
InvalidatePipeline();
}
inline void MaterialPass::SetBlendFunc(BlendFunc srcColor, BlendFunc dstColor, BlendFunc srcAlpha, BlendFunc dstAlpha)
{
m_pipelineInfo.blend.dstAlpha = dstAlpha;
m_pipelineInfo.blend.dstColor = dstColor;
m_pipelineInfo.blend.srcAlpha = srcAlpha;
m_pipelineInfo.blend.srcColor = srcColor;
InvalidatePipeline();
}
/*!
* \brief Sets the face culling
*
* \param faceSide Face to cull
*
* \remark Invalidates the pipeline
*/
inline void MaterialPass::SetFaceCulling(FaceSide faceSide)
{
m_pipelineInfo.cullingSide = faceSide;
InvalidatePipeline();
}
/*!
* \brief Sets the face filling
*
* \param filling Face to fill
*
* \remark Invalidates the pipeline
*/
inline void MaterialPass::SetFaceFilling(FaceFilling filling)
{
m_pipelineInfo.faceFilling = filling;
InvalidatePipeline();
}
/*!
* \brief Sets the line width for this material
*
* This parameter is used when rendering lines, to define the width (in pixels) the line will take on the framebuffer
*
* \param lineWidth Width of the line
*
* \remark Invalidates the pipeline
*
* \see GetLineWidth
*/
inline void MaterialPass::SetLineWidth(float lineWidth)
{
m_pipelineInfo.lineWidth = lineWidth;
InvalidatePipeline();
}
inline void MaterialPass::SetOptionValue(std::size_t optionIndex, nzsl::Ast::ConstantSingleValue value)
{
assert(optionIndex < m_optionValues.size());
if (m_optionValues[optionIndex] != value)
{
m_optionValues[optionIndex] = std::move(value);
InvalidatePipeline();
}
}
/*!
* \brief Sets the point size for this material
*
* This parameter is used when rendering points, to define the size (in pixels) the point will take on the framebuffer
*
* \param pointSize Size of the point
*
* \remark Invalidates the pipeline
*
* \see GetPointSize
*/
inline void MaterialPass::SetPointSize(float pointSize)
{
m_pipelineInfo.pointSize = pointSize;
InvalidatePipeline();
}
inline void MaterialPass::SetPrimitiveMode(PrimitiveMode mode)
{
m_pipelineInfo.primitiveMode = mode;
InvalidatePipeline();
}
inline void MaterialPass::SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer)
{
if (uniformBuffer)
{
UInt64 size = uniformBuffer->GetSize();
return SetSharedUniformBuffer(sharedUboIndex, std::move(uniformBuffer), 0, size);
}
else
return SetSharedUniformBuffer(sharedUboIndex, std::move(uniformBuffer), 0, 0);
}
inline void MaterialPass::SetSharedUniformBuffer(std::size_t sharedUboIndex, std::shared_ptr<RenderBuffer> uniformBuffer, UInt64 offset, UInt64 size)
{
NazaraAssert(sharedUboIndex < m_sharedUniformBuffers.size(), "Invalid shared uniform buffer index");
RenderBufferView bufferView(uniformBuffer.get(), offset, size);
if (m_sharedUniformBuffers[sharedUboIndex].bufferView != bufferView)
{
m_sharedUniformBuffers[sharedUboIndex].bufferView = bufferView;
m_sharedUniformBuffers[sharedUboIndex].buffer = std::move(uniformBuffer);
InvalidateShaderBinding();
}
}
inline void MaterialPass::SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture)
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
if (m_textures[textureIndex].texture != texture)
{
m_textures[textureIndex].texture = std::move(texture);
InvalidateShaderBinding();
}
}
inline void MaterialPass::SetTextureSampler(std::size_t textureIndex, TextureSamplerInfo samplerInfo)
{
NazaraAssert(textureIndex < m_textures.size(), "Invalid texture index");
if (m_textures[textureIndex].samplerInfo != samplerInfo)
{
m_textures[textureIndex].samplerInfo = std::move(samplerInfo);
InvalidateTextureSampler(textureIndex);
}
}
inline void MaterialPass::InvalidatePipeline()
{
m_pipelineUpdated = false;
OnMaterialPassPipelineInvalidated(this);
}
inline void MaterialPass::InvalidateShaderBinding()
{
OnMaterialPassShaderBindingInvalidated(this);
}
inline void MaterialPass::InvalidateTextureSampler(std::size_t textureIndex)
{
assert(textureIndex < m_textures.size());
m_textures[textureIndex].sampler.reset();
InvalidateShaderBinding();
}
inline void MaterialPass::InvalidateUniformData(std::size_t uniformBufferIndex)
{
assert(uniformBufferIndex < m_uniformBuffers.size());
UniformBuffer& uboEntry = m_uniformBuffers[uniformBufferIndex];
uboEntry.dataInvalidated = true;
OnMaterialPassInvalidated(this);
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -8,6 +8,8 @@
#define NAZARA_GRAPHICS_MATERIALPASSREGISTRY_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Utils/Algorithm.hpp>
#include <list>
#include <string>
#include <unordered_map>
@ -21,7 +23,7 @@ namespace Nz
MaterialPassRegistry(MaterialPassRegistry&&) = default;
~MaterialPassRegistry() = default;
inline std::size_t GetPassIndex(const std::string& passName) const;
inline std::size_t GetPassIndex(std::string_view passName) const;
inline std::size_t RegisterPass(std::string passName);
@ -29,7 +31,8 @@ namespace Nz
MaterialPassRegistry& operator=(MaterialPassRegistry&&) = default;
private:
std::unordered_map<std::string, std::size_t> m_passIndex;
std::list<std::string> m_passNames; //< in order to allow std::string_view as a key in C++17 (keep std::string stable as well because of SSO)
std::unordered_map<std::string_view, std::size_t> m_passIndex;
};
}

View File

@ -8,11 +8,11 @@
namespace Nz
{
std::size_t MaterialPassRegistry::GetPassIndex(const std::string& passName) const
std::size_t MaterialPassRegistry::GetPassIndex(std::string_view passName) const
{
auto it = m_passIndex.find(passName);
if (it == m_passIndex.end())
throw std::runtime_error("pass " + passName + " must be registered before being used");
throw std::runtime_error("pass " + std::string(passName) + " must be registered before being used");
return it->second;
}
@ -22,8 +22,10 @@ namespace Nz
if (m_passIndex.find(passName) != m_passIndex.end())
throw std::runtime_error("pass " + passName + " is already registered");
m_passNames.push_back(std::move(passName));
std::size_t passIndex = m_passIndex.size();
m_passIndex.emplace(std::move(passName), passIndex);
m_passIndex.emplace(m_passNames.back(), passIndex);
return passIndex;
}

View File

@ -10,7 +10,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Renderer/RenderPipeline.hpp>
#include <NZSL/Ast/ConstantValue.hpp>
#include <array>
@ -33,10 +33,9 @@ namespace Nz
std::shared_ptr<UberShader> uberShader;
};
std::array<Option, 32> optionValues;
std::size_t optionCount = 0;
std::vector<Shader> shaders;
std::shared_ptr<const MaterialSettings> settings;
std::shared_ptr<RenderPipelineLayout> pipelineLayout;
std::vector<Option> optionValues; //< TODO: FixedVector
std::vector<Shader> shaders; //< TODO: FixedVector
};
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);

View File

@ -40,16 +40,13 @@ namespace Nz
#define NazaraPipelineMember(field) if (lhs.field != rhs.field) return false
NazaraPipelineMember(settings);
NazaraPipelineMember(optionCount);
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
{
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
return false;
}
for (std::size_t i = 0; i < lhs.optionCount; ++i)
for (std::size_t i = 0; i < lhs.optionValues.size(); ++i)
{
if (lhs.optionValues[i].hash != rhs.optionValues[i].hash)
return false;
@ -86,9 +83,7 @@ namespace std
#define NazaraPipelineMember(member) Nz::HashCombine(seed, pipelineInfo.member)
#define NazaraPipelineBoolMember(member) parameterHash |= ((pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
NazaraPipelineMember(settings.get()); //< Hash pointer
for (std::size_t i = 0; i < pipelineInfo.optionCount; ++i)
for (std::size_t i = 0; i < pipelineInfo.optionValues.size(); ++i)
{
Nz::HashCombine(seed, pipelineInfo.optionValues[i].hash);
Nz::HashCombine(seed, pipelineInfo.optionValues[i].value);

View File

@ -8,110 +8,100 @@
#define NAZARA_GRAPHICS_MATERIALSETTINGS_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Color.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/UberShader.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/ShaderModule.hpp>
#include <Nazara/Utility/Enums.hpp>
#include <array>
#include <Nazara/Graphics/MaterialPass.hpp>
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/Math/Vector3.hpp>
#include <Nazara/Math/Vector4.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Utils/TypeList.hpp>
#include <limits>
#include <optional>
#include <string>
#include <variant>
#include <vector>
namespace Nz
{
class MaterialSettings
template<typename T> struct TypeToMaterialPropertyType;
template<typename T> constexpr MaterialPropertyType TypeToMaterialPropertyType_v = TypeToMaterialPropertyType<T>::PropertyType;
template<MaterialPropertyType P> struct MaterialPropertyTypeInfo;
struct MaterialPropertyNoValue {};
using MaterialPropertyTypeList = TypeList<
MaterialPropertyNoValue,
Color,
bool, Vector2<bool>, Vector3<bool>, Vector4<bool>,
float, Vector2<float>, Vector3<float>, Vector4<float>,
Int32, Vector2<Int32>, Vector3<Int32>, Vector4<Int32>,
UInt32, Vector2<UInt32>, Vector3<UInt32>, Vector4<UInt32>
>;
class NAZARA_GRAPHICS_API MaterialSettings
{
public:
struct Builder;
struct Option;
struct SharedUniformBlock;
struct Texture;
struct UniformBlock;
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
struct TextureProperty;
struct ValueProperty;
inline MaterialSettings();
inline MaterialSettings(Builder builder);
MaterialSettings(const MaterialSettings&) = default;
MaterialSettings(MaterialSettings&&) = delete;
using Value = TypeListInstantiate<MaterialPropertyTypeList, std::variant>;
MaterialSettings() = default;
MaterialSettings(const MaterialSettings&) = delete;
MaterialSettings(MaterialSettings&&) noexcept = default;
~MaterialSettings() = default;
inline const Builder& GetBuilderData() const;
inline const std::vector<Option>& GetOptions() const;
inline std::size_t GetOptionIndex(const std::string_view& name) const;
inline std::size_t GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const;
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
inline const std::shared_ptr<UberShader>& GetShader(nzsl::ShaderStageType stage) const;
inline const std::vector<std::shared_ptr<UberShader>>& GetShaders() const;
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
inline std::size_t GetSharedUniformBlockIndex(const std::string_view& name) const;
inline std::size_t GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
inline const std::vector<Texture>& GetTextures() const;
inline std::size_t GetTextureIndex(const std::string_view& name) const;
inline const std::vector<UniformBlock>& GetUniformBlocks() const;
inline std::size_t GetUniformBlockIndex(const std::string_view& name) const;
inline std::size_t GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
void AddPass(std::string_view passName, MaterialPass materialPass);
inline void AddPass(std::size_t passIndex, MaterialPass materialPass);
inline void AddPropertyHandler(std::unique_ptr<PropertyHandler> propertyHandler);
inline void AddTextureProperty(std::string propertyName, ImageType propertyType);
inline void AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture);
inline void AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture, const TextureSamplerInfo& defaultSamplerInfo);
inline void AddValueProperty(std::string propertyName, MaterialPropertyType propertyType, Value defaultValue);
template<typename T> void AddValueProperty(std::string propertyName);
template<typename T, typename U> void AddValueProperty(std::string propertyName, U&& defaultValue);
inline std::size_t FindTextureProperty(std::string_view propertyName) const;
inline std::size_t FindValueProperty(std::string_view propertyName) const;
const MaterialPass* GetPass(std::string_view passName) const;
inline const MaterialPass* GetPass(std::size_t passIndex) const;
inline const std::vector<std::optional<MaterialPass>>& GetPasses() const;
inline const std::vector<std::unique_ptr<PropertyHandler>>& GetPropertyHandlers() const;
inline const TextureProperty& GetTextureProperty(std::size_t texturePropertyIndex) const;
inline std::size_t GetTexturePropertyCount() const;
inline const ValueProperty& GetValueProperty(std::size_t valuePropertyIndex) const;
inline std::size_t GetValuePropertyCount() const;
MaterialSettings& operator=(const MaterialSettings&) = delete;
MaterialSettings& operator=(MaterialSettings&&) = delete;
MaterialSettings& operator=(MaterialSettings&&) = default;
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
static inline void BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName);
struct Builder
struct TextureProperty
{
inline Builder();
std::vector<std::shared_ptr<UberShader>> shaders;
std::vector<Option> options;
std::vector<Texture> textures;
std::vector<UniformBlock> uniformBlocks;
std::vector<SharedUniformBlock> sharedUniformBlocks;
PredefinedBinding predefinedBindings;
};
struct Option
{
std::string name;
UInt32 hash;
};
struct UniformVariable
{
std::string name;
std::size_t offset;
};
struct SharedUniformBlock
{
UInt32 bindingIndex;
std::string name;
std::vector<UniformVariable> uniforms;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
};
struct Texture
{
UInt32 bindingIndex;
std::shared_ptr<Texture> defaultTexture;
std::string name;
ImageType type;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
TextureSamplerInfo defaultSamplerInfo;
};
struct UniformBlock
struct ValueProperty
{
UInt32 bindingIndex;
Value defaultValue;
std::string name;
std::size_t blockSize;
std::vector<UniformVariable> uniforms;
std::vector<UInt8> defaultValues;
nzsl::ShaderStageTypeFlags shaderStages = nzsl::ShaderStageType_All;
MaterialPropertyType type;
};
static constexpr std::size_t InvalidPropertyIndex = std::numeric_limits<std::size_t>::max();
private:
std::shared_ptr<RenderPipelineLayout> m_pipelineLayout;
Builder m_data;
std::vector<std::unique_ptr<PropertyHandler>> m_propertyHandlers;
std::vector<std::optional<MaterialPass>> m_materialPasses;
std::vector<TextureProperty> m_textureProperties;
std::vector<ValueProperty> m_valueProperties;
};
}

View File

@ -3,186 +3,327 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/MaterialSettings.hpp>
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Graphics/Graphics.hpp>
#include <cassert>
#include <Nazara/Utils/Algorithm.hpp>
#include <stdexcept>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline MaterialSettings::MaterialSettings() :
MaterialSettings(Builder{})
template<typename T> class Vector2;
template<typename T> class Vector3;
template<typename T> class Vector4;
template<typename T>
struct TypeToMaterialPropertyType
{
static_assert(AlwaysFalse<T>(), "T is not a valid type for material property");
};
template<> struct TypeToMaterialPropertyType<bool> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool; };
template<> struct TypeToMaterialPropertyType<Vector2<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool2; };
template<> struct TypeToMaterialPropertyType<Vector3<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool3; };
template<> struct TypeToMaterialPropertyType<Vector4<bool>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Bool4; };
template<> struct TypeToMaterialPropertyType<Color> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Color; };
template<> struct TypeToMaterialPropertyType<float> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float; };
template<> struct TypeToMaterialPropertyType<Vector2<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float2; };
template<> struct TypeToMaterialPropertyType<Vector3<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float3; };
template<> struct TypeToMaterialPropertyType<Vector4<float>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Float4; };
template<> struct TypeToMaterialPropertyType<Int32> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int; };
template<> struct TypeToMaterialPropertyType<Vector2<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int2; };
template<> struct TypeToMaterialPropertyType<Vector3<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int3; };
template<> struct TypeToMaterialPropertyType<Vector4<Int32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::Int4; };
template<> struct TypeToMaterialPropertyType<UInt32> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt; };
template<> struct TypeToMaterialPropertyType<Vector2<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt2; };
template<> struct TypeToMaterialPropertyType<Vector3<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt3; };
template<> struct TypeToMaterialPropertyType<Vector4<UInt32>> { static constexpr MaterialPropertyType PropertyType = MaterialPropertyType::UInt4; };
template<MaterialPropertyType P>
struct MaterialPropertyTypeInfo
{
};
template<typename T>
struct MaterialPropertyTypeInfoPrimitive
{
using Type = T;
using BufferType = T;
using OptionType = T;
static Type DecodeFromBuffer(BufferType value) { return value; }
static Type DecodeFromOption(OptionType value) { return value; }
static BufferType EncodeToBuffer(Type value) { return value; }
static OptionType EncodeToOption(Type value) { return value; }
};
template<typename T, std::size_t N>
struct MaterialPropertyTypeInfoVector;
template<typename T>
struct MaterialPropertyTypeInfoVector<T, 2>
{
using Type = Vector2<T>;
using BufferType = nzsl::Vector2<T>;
using OptionType = nzsl::Vector2<T>;
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y() }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y }; }
};
template<typename T>
struct MaterialPropertyTypeInfoVector<T, 3>
{
using Type = Vector3<T>;
using BufferType = nzsl::Vector3<T>;
using OptionType = nzsl::Vector3<T>;
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z() }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z }; }
};
template<typename T>
struct MaterialPropertyTypeInfoVector<T, 4>
{
using Type = Vector4<T>;
using BufferType = nzsl::Vector4<T>;
using OptionType = nzsl::Vector4<T>;
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z(), value.w() }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z, value.w }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z, value.w }; }
};
template<>
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool>
{
using Type = bool;
using BufferType = UInt32;
using OptionType = bool;
static Type DecodeFromBuffer(BufferType value) { return value != 0; }
static Type DecodeFromOption(OptionType value) { return value; }
static BufferType EncodeToBuffer(Type value) { return value; }
static OptionType EncodeToOption(Type value) { return value; }
};
template<>
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool2>
{
using Type = Vector2<bool>;
using BufferType = nzsl::Vector2u32;
using OptionType = nzsl::Vector2<bool>;
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0 }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y }; }
};
template<>
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool3>
{
using Type = Vector3<bool>;
using BufferType = nzsl::Vector3u32;
using OptionType = nzsl::Vector3<bool>;
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0, value.z() != 0 }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z }; }
};
template<>
struct MaterialPropertyTypeInfo<MaterialPropertyType::Bool4>
{
using Type = Vector4<bool>;
using BufferType = nzsl::Vector4u32;
using OptionType = nzsl::Vector4<bool>;
static Type DecodeFromBuffer(BufferType value) { return { value.x() != 0, value.y() != 0, value.z() != 0, value.w() != 0}; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.x, value.y, value.z, value.w }; }
static OptionType EncodeToOption(Type value) { return OptionType{ value.x, value.y, value.z, value.w }; }
};
template<>
struct MaterialPropertyTypeInfo<MaterialPropertyType::Color>
{
using Type = Color;
using BufferType = nzsl::Vector4f32;
using OptionType = nzsl::Vector4f32;
static Type DecodeFromBuffer(BufferType value) { return { value.x(), value.y(), value.z(), value.w() }; }
static Type DecodeFromOption(OptionType value) { return { value.x(), value.y(), value.z(), value.w() }; }
static BufferType EncodeToBuffer(Type value) { return BufferType{ value.r, value.g, value.b, value.a }; }
static OptionType EncodeToOption(Type value) { return BufferType{ value.r, value.g, value.b, value.a }; }
};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float> : MaterialPropertyTypeInfoPrimitive<float> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float2> : MaterialPropertyTypeInfoVector<float, 2> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float3> : MaterialPropertyTypeInfoVector<float, 3> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Float4> : MaterialPropertyTypeInfoVector<float, 4> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int> : MaterialPropertyTypeInfoPrimitive<Int32> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int2> : MaterialPropertyTypeInfoVector<Int32, 2> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int3> : MaterialPropertyTypeInfoVector<Int32, 3> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::Int4> : MaterialPropertyTypeInfoVector<Int32, 4> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt> : MaterialPropertyTypeInfoPrimitive<UInt32> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt2> : MaterialPropertyTypeInfoVector<UInt32, 2> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt3> : MaterialPropertyTypeInfoVector<UInt32, 3> {};
template<> struct MaterialPropertyTypeInfo<MaterialPropertyType::UInt4> : MaterialPropertyTypeInfoVector<UInt32, 4> {};
inline void MaterialSettings::AddPass(std::size_t passIndex, MaterialPass materialPass)
{
if (passIndex >= m_materialPasses.size())
m_materialPasses.resize(passIndex + 1);
m_materialPasses[passIndex] = std::move(materialPass);
}
inline MaterialSettings::MaterialSettings(Builder data) :
m_data(std::move(data))
inline void MaterialSettings::AddPropertyHandler(std::unique_ptr<PropertyHandler> propertyHandler)
{
RenderPipelineLayoutInfo info;
for (const Texture& textureInfo : m_data.textures)
{
info.bindings.push_back({
0,
textureInfo.bindingIndex,
ShaderBindingType::Texture,
textureInfo.shaderStages
});
}
for (const UniformBlock& ubo : m_data.uniformBlocks)
{
info.bindings.push_back({
0,
ubo.bindingIndex,
ShaderBindingType::UniformBuffer,
ubo.shaderStages
});
}
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
{
info.bindings.push_back({
0,
ubo.bindingIndex,
ShaderBindingType::UniformBuffer,
ubo.shaderStages
});
}
m_pipelineLayout = Graphics::Instance()->GetRenderDevice()->InstantiateRenderPipelineLayout(std::move(info));
m_propertyHandlers.emplace_back(std::move(propertyHandler));
}
inline auto MaterialSettings::GetBuilderData() const -> const Builder&
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType)
{
return m_data;
auto& textureProperty = m_textureProperties.emplace_back();
textureProperty.name = std::move(propertyName);
textureProperty.type = propertyType;
}
inline auto MaterialSettings::GetOptions() const -> const std::vector<Option>&
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture)
{
return m_data.options;
if (defaultTexture && defaultTexture->GetType() != propertyType)
throw std::runtime_error("default texture type doesn't match property image type");
auto& textureProperty = m_textureProperties.emplace_back();
textureProperty.name = std::move(propertyName);
textureProperty.type = propertyType;
textureProperty.defaultTexture = std::move(defaultTexture);
}
inline std::size_t MaterialSettings::GetOptionIndex(const std::string_view& name) const
inline void MaterialSettings::AddTextureProperty(std::string propertyName, ImageType propertyType, std::shared_ptr<Texture> defaultTexture, const TextureSamplerInfo& defaultSamplerInfo)
{
for (std::size_t i = 0; i < m_data.options.size(); ++i)
if (defaultTexture && defaultTexture->GetType() != propertyType)
throw std::runtime_error("default texture type doesn't match property image type");
auto& textureProperty = m_textureProperties.emplace_back();
textureProperty.name = std::move(propertyName);
textureProperty.type = propertyType;
textureProperty.defaultTexture = std::move(defaultTexture);
textureProperty.defaultSamplerInfo = defaultSamplerInfo;
}
inline void MaterialSettings::AddValueProperty(std::string propertyName, MaterialPropertyType propertyType, Value defaultValue)
{
std::visit([&](auto&& arg)
{
if (m_data.options[i].name == name)
using T = std::decay_t<decltype(arg)>;
if constexpr (!std::is_same_v<T, MaterialPropertyNoValue>)
{
constexpr MaterialPropertyType valueType = TypeToMaterialPropertyType_v<T>;
if (propertyType != valueType)
throw std::runtime_error("default value type doesn't match property type");
}
else
throw std::runtime_error("value properties must have a default value");
}, defaultValue);
auto& valueProperty = m_valueProperties.emplace_back();
valueProperty.name = std::move(propertyName);
valueProperty.type = propertyType;
valueProperty.defaultValue = std::move(defaultValue);
}
inline std::size_t MaterialSettings::FindTextureProperty(std::string_view propertyName) const
{
for (std::size_t i = 0; i < m_textureProperties.size(); ++i)
{
if (m_textureProperties[i].name == propertyName)
return i;
}
return InvalidIndex;
return InvalidPropertyIndex;
}
inline std::size_t MaterialSettings::GetPredefinedBinding(PredefinedShaderBinding shaderBinding) const
inline std::size_t MaterialSettings::FindValueProperty(std::string_view propertyName) const
{
return m_data.predefinedBindings[UnderlyingCast(shaderBinding)];
}
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
{
return m_pipelineLayout;
}
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(nzsl::ShaderStageType stage) const
{
return m_data.shaders[UnderlyingCast(stage)];
}
inline const std::vector<std::shared_ptr<UberShader>>& MaterialSettings::GetShaders() const
{
return m_data.shaders;
}
inline auto MaterialSettings::GetSharedUniformBlocks() const -> const std::vector<SharedUniformBlock>&
{
return m_data.sharedUniformBlocks;
}
inline std::size_t MaterialSettings::GetSharedUniformBlockIndex(const std::string_view& name) const
{
for (std::size_t i = 0; i < m_data.sharedUniformBlocks.size(); ++i)
for (std::size_t i = 0; i < m_valueProperties.size(); ++i)
{
if (m_data.sharedUniformBlocks[i].name == name)
if (m_valueProperties[i].name == propertyName)
return i;
}
return InvalidIndex;
return InvalidPropertyIndex;
}
inline std::size_t MaterialSettings::GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
inline const MaterialPass* MaterialSettings::GetPass(std::size_t passIndex) const
{
assert(uniformBlockIndex < m_data.sharedUniformBlocks.size());
if (passIndex > m_materialPasses.size() || !m_materialPasses[passIndex].has_value())
return nullptr;
const std::vector<UniformVariable>& variables = m_data.sharedUniformBlocks[uniformBlockIndex].uniforms;
for (std::size_t i = 0; i < variables.size(); ++i)
{
if (variables[i].name == name)
return i;
}
return InvalidIndex;
return &m_materialPasses[passIndex].value();
}
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
inline const std::vector<std::optional<MaterialPass>>& MaterialSettings::GetPasses() const
{
return m_data.textures;
return m_materialPasses;
}
inline std::size_t MaterialSettings::GetTextureIndex(const std::string_view& name) const
inline const std::vector<std::unique_ptr<PropertyHandler>>& MaterialSettings::GetPropertyHandlers() const
{
for (std::size_t i = 0; i < m_data.textures.size(); ++i)
{
if (m_data.textures[i].name == name)
return i;
}
return InvalidIndex;
return m_propertyHandlers;
}
inline auto MaterialSettings::GetUniformBlocks() const -> const std::vector<UniformBlock>&
inline auto MaterialSettings::GetTextureProperty(std::size_t texturePropertyIndex) const -> const TextureProperty&
{
return m_data.uniformBlocks;
assert(texturePropertyIndex < m_textureProperties.size());
return m_textureProperties[texturePropertyIndex];
}
inline std::size_t MaterialSettings::GetUniformBlockIndex(const std::string_view& name) const
inline std::size_t MaterialSettings::GetTexturePropertyCount() const
{
for (std::size_t i = 0; i < m_data.uniformBlocks.size(); ++i)
{
if (m_data.uniformBlocks[i].name == name)
return i;
}
return InvalidIndex;
return m_textureProperties.size();
}
inline std::size_t MaterialSettings::GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
inline auto MaterialSettings::GetValueProperty(std::size_t valuePropertyIndex) const -> const ValueProperty&
{
assert(uniformBlockIndex < m_data.uniformBlocks.size());
const std::vector<UniformVariable>& variables = m_data.uniformBlocks[uniformBlockIndex].uniforms;
for (std::size_t i = 0; i < variables.size(); ++i)
{
if (variables[i].name == name)
return i;
}
return InvalidIndex;
assert(valuePropertyIndex < m_valueProperties.size());
return m_valueProperties[valuePropertyIndex];
}
inline void MaterialSettings::BuildOption(std::vector<Option>& options, std::string optionName, const std::string& shaderOptionName)
inline std::size_t MaterialSettings::GetValuePropertyCount() const
{
UInt32 optionHash = CRC32(shaderOptionName);
options.push_back({
std::move(optionName),
optionHash
});
return m_valueProperties.size();
}
inline MaterialSettings::Builder::Builder()
template<typename T>
void MaterialSettings::AddValueProperty(std::string propertyName)
{
predefinedBindings.fill(InvalidIndex);
return AddValueProperty(std::move(propertyName), TypeToMaterialPropertyType_v<T>);
}
template<typename T, typename U>
void MaterialSettings::AddValueProperty(std::string propertyName, U&& defaultValue)
{
constexpr std::size_t TypeIndex = TypeListFind<MaterialPropertyTypeList, T>;
auto& valueProperty = m_valueProperties.emplace_back();
valueProperty.name = std::move(propertyName);
valueProperty.type = TypeToMaterialPropertyType_v<T>;
valueProperty.defaultValue.emplace<TypeIndex>(std::forward<U>(defaultValue));
}
}

View File

@ -32,13 +32,13 @@ namespace Nz
const std::shared_ptr<RenderBuffer>& GetIndexBuffer(std::size_t subMeshIndex) const;
std::size_t GetIndexCount(std::size_t subMeshIndex) const;
const std::shared_ptr<Material>& GetMaterial(std::size_t subMeshIndex) const override;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t subMeshIndex) const override;
std::size_t GetMaterialCount() const override;
inline std::size_t GetSubMeshCount() const;
const std::vector<RenderPipelineInfo::VertexBufferData>& GetVertexBufferData(std::size_t subMeshIndex) const;
const std::shared_ptr<RenderBuffer>& GetVertexBuffer(std::size_t subMeshIndex) const;
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material);
inline void SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialInstance> material);
Model& operator=(const Model&) = delete;
Model& operator=(Model&&) noexcept = default;
@ -46,7 +46,7 @@ namespace Nz
private:
struct SubMeshData
{
std::shared_ptr<Material> material;
std::shared_ptr<MaterialInstance> material;
std::vector<RenderPipelineInfo::VertexBufferData> vertexBufferData;
};

View File

@ -13,14 +13,14 @@ namespace Nz
return m_submeshes.size();
}
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<Material> material)
inline void Model::SetMaterial(std::size_t subMeshIndex, std::shared_ptr<MaterialInstance> material)
{
assert(subMeshIndex < m_submeshes.size());
assert(material);
if (m_submeshes[subMeshIndex].material != material)
{
OnMaterialInvalidated(this, 0, material);
OnMaterialInvalidated(this, subMeshIndex, material);
m_submeshes[subMeshIndex].material = std::move(material);
OnElementInvalidated(this);

View File

@ -1,111 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PHONGLIGHTINGMATERIAL_HPP
#define NAZARA_GRAPHICS_PHONGLIGHTINGMATERIAL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
namespace Nz
{
class NAZARA_GRAPHICS_API PhongLightingMaterial : public BasicMaterial
{
friend class MaterialPipeline;
public:
PhongLightingMaterial(MaterialPass& material);
Color GetAmbientColor() const;
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
inline const TextureSamplerInfo& GetEmissiveSampler() const;
inline const std::shared_ptr<Texture>& GetHeightMap() const;
inline const TextureSamplerInfo& GetHeightSampler() const;
inline const std::shared_ptr<Texture>& GetNormalMap() const;
inline const TextureSamplerInfo& GetNormalSampler() const;
float GetShininess() const;
Color GetSpecularColor() const;
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
inline const TextureSamplerInfo& GetSpecularSampler() const;
inline bool HasAmbientColor() const;
inline bool HasEmissiveMap() const;
inline bool HasHeightMap() const;
inline bool HasNormalMap() const;
inline bool HasShininess() const;
inline bool HasSpecularColor() const;
inline bool HasSpecularMap() const;
void SetAmbientColor(const Color& ambient);
inline void SetEmissiveMap(std::shared_ptr<Texture> emissiveMap);
inline void SetEmissiveSampler(TextureSamplerInfo emissiveSampler);
inline void SetHeightMap(std::shared_ptr<Texture> heightMap);
inline void SetHeightSampler(TextureSamplerInfo heightSampler);
inline void SetNormalMap(std::shared_ptr<Texture> normalMap);
inline void SetNormalSampler(TextureSamplerInfo normalSampler);
void SetShininess(float shininess);
void SetSpecularColor(const Color& specular);
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
inline void SetSpecularSampler(TextureSamplerInfo specularSampler);
static const std::shared_ptr<MaterialSettings>& GetSettings();
protected:
struct PhongOptionIndexes
{
std::size_t hasEmissiveMap;
std::size_t hasHeightMap;
std::size_t hasNormalMap;
std::size_t hasSpecularMap;
};
struct PhongUniformOffsets
{
std::size_t ambientColor;
std::size_t shininess;
std::size_t totalSize;
std::size_t specularColor;
};
struct PhongTextureIndexes
{
std::size_t emissive;
std::size_t height;
std::size_t normal;
std::size_t specular;
};
struct PhongBuildOptions : BasicBuildOptions
{
PhongUniformOffsets phongOffsets;
PhongOptionIndexes* phongOptionIndexes = nullptr;
PhongTextureIndexes* phongTextureIndexes = nullptr;
};
PhongOptionIndexes m_phongOptionIndexes;
PhongTextureIndexes m_phongTextureIndexes;
PhongUniformOffsets m_phongUniformOffsets;
static MaterialSettings::Builder Build(PhongBuildOptions& options);
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
static std::pair<PhongUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
private:
static bool Initialize();
static void Uninitialize();
static std::shared_ptr<MaterialSettings> s_phongMaterialSettings;
static std::size_t s_phongUniformBlockIndex;
static PhongOptionIndexes s_phongOptionIndexes;
static PhongTextureIndexes s_phongTextureIndexes;
static PhongUniformOffsets s_phongUniformOffsets;
};
}
#include <Nazara/Graphics/PhongLightingMaterial.inl>
#endif // NAZARA_GRAPHICS_PHONGLIGHTINGMATERIAL_HPP

View File

@ -1,160 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetEmissiveMap() const
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
return GetMaterial().GetTexture(m_phongTextureIndexes.emissive);
}
inline const TextureSamplerInfo& PhongLightingMaterial::GetEmissiveSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no emissive map slot");
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.emissive);
}
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetHeightMap() const
{
NazaraAssert(HasHeightMap(), "Material has no height map slot");
return GetMaterial().GetTexture(m_phongTextureIndexes.height);
}
inline const TextureSamplerInfo& PhongLightingMaterial::GetHeightSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no height map slot");
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.height);
}
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetNormalMap() const
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
return GetMaterial().GetTexture(m_phongTextureIndexes.normal);
}
inline const TextureSamplerInfo& PhongLightingMaterial::GetNormalSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no normal map slot");
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.normal);
}
inline const std::shared_ptr<Texture>& PhongLightingMaterial::GetSpecularMap() const
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
return GetMaterial().GetTexture(m_phongTextureIndexes.specular);
}
inline const TextureSamplerInfo& PhongLightingMaterial::GetSpecularSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
return GetMaterial().GetTextureSampler(m_phongTextureIndexes.specular);
}
inline bool PhongLightingMaterial::HasAmbientColor() const
{
return m_phongUniformOffsets.ambientColor != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasEmissiveMap() const
{
return m_phongTextureIndexes.emissive != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasHeightMap() const
{
return m_phongTextureIndexes.height != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasNormalMap() const
{
return m_phongTextureIndexes.normal != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasShininess() const
{
return m_phongUniformOffsets.shininess != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasSpecularColor() const
{
return m_phongUniformOffsets.specularColor != MaterialSettings::InvalidIndex;
}
inline bool PhongLightingMaterial::HasSpecularMap() const
{
return m_phongTextureIndexes.specular != MaterialSettings::InvalidIndex;
}
inline void PhongLightingMaterial::SetEmissiveMap(std::shared_ptr<Texture> emissiveMap)
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
bool hasEmissiveMap = (emissiveMap != nullptr);
GetMaterial().SetTexture(m_phongTextureIndexes.emissive, std::move(emissiveMap));
if (m_phongOptionIndexes.hasEmissiveMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasEmissiveMap, hasEmissiveMap);
}
inline void PhongLightingMaterial::SetEmissiveSampler(TextureSamplerInfo emissiveSampler)
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
GetMaterial().SetTextureSampler(m_phongTextureIndexes.emissive, std::move(emissiveSampler));
}
inline void PhongLightingMaterial::SetHeightMap(std::shared_ptr<Texture> heightMap)
{
NazaraAssert(HasHeightMap(), "Material has no specular map slot");
bool hasHeightMap = (heightMap != nullptr);
GetMaterial().SetTexture(m_phongTextureIndexes.height, std::move(heightMap));
if (m_phongOptionIndexes.hasHeightMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasHeightMap, hasHeightMap);
}
inline void PhongLightingMaterial::SetHeightSampler(TextureSamplerInfo heightSampler)
{
NazaraAssert(HasHeightMap(), "Material has no height map slot");
GetMaterial().SetTextureSampler(m_phongTextureIndexes.height, std::move(heightSampler));
}
inline void PhongLightingMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
bool hasNormalMap = (normalMap != nullptr);
GetMaterial().SetTexture(m_phongTextureIndexes.normal, std::move(normalMap));
if (m_phongOptionIndexes.hasNormalMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasNormalMap, hasNormalMap);
}
inline void PhongLightingMaterial::SetNormalSampler(TextureSamplerInfo normalSampler)
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
GetMaterial().SetTextureSampler(m_phongTextureIndexes.normal, std::move(normalSampler));
}
inline void PhongLightingMaterial::SetSpecularMap(std::shared_ptr<Texture> specularMap)
{
NazaraAssert(HasNormalMap(), "Material has no specular map slot");
bool hasSpecularMap = (specularMap != nullptr);
GetMaterial().SetTexture(m_phongTextureIndexes.specular, std::move(specularMap));
if (m_phongOptionIndexes.hasSpecularMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_phongOptionIndexes.hasSpecularMap, hasSpecularMap);
}
inline void PhongLightingMaterial::SetSpecularSampler(TextureSamplerInfo specularSampler)
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
GetMaterial().SetTextureSampler(m_phongTextureIndexes.specular, std::move(specularSampler));
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -1,125 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PHYSICALLYBASEDMATERIAL_HPP
#define NAZARA_GRAPHICS_PHYSICALLYBASEDMATERIAL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/BasicMaterial.hpp>
#include <Nazara/Graphics/MaterialPass.hpp>
namespace Nz
{
class NAZARA_GRAPHICS_API PhysicallyBasedMaterial : public BasicMaterial
{
friend class MaterialPipeline;
public:
PhysicallyBasedMaterial(MaterialPass& material);
Color GetAmbientColor() const;
inline const std::shared_ptr<Texture>& GetEmissiveMap() const;
inline const TextureSamplerInfo& GetEmissiveSampler() const;
inline const std::shared_ptr<Texture>& GetHeightMap() const;
inline const TextureSamplerInfo& GetHeightSampler() const;
inline const std::shared_ptr<Texture>& GetMetallicMap() const;
inline const TextureSamplerInfo& GetMetallicSampler() const;
inline const std::shared_ptr<Texture>& GetNormalMap() const;
inline const TextureSamplerInfo& GetNormalSampler() const;
inline const std::shared_ptr<Texture>& GetRoughnessMap() const;
inline const TextureSamplerInfo& GetRoughnessSampler() const;
float GetShininess() const;
Color GetSpecularColor() const;
inline const std::shared_ptr<Texture>& GetSpecularMap() const;
inline const TextureSamplerInfo& GetSpecularSampler() const;
inline bool HasAmbientColor() const;
inline bool HasEmissiveMap() const;
inline bool HasHeightMap() const;
inline bool HasMetallicMap() const;
inline bool HasNormalMap() const;
inline bool HasRoughnessMap() const;
inline bool HasShininess() const;
inline bool HasSpecularColor() const;
inline bool HasSpecularMap() const;
void SetAmbientColor(const Color& ambient);
inline void SetEmissiveMap(std::shared_ptr<Texture> emissiveMap);
inline void SetEmissiveSampler(TextureSamplerInfo emissiveSampler);
inline void SetHeightMap(std::shared_ptr<Texture> heightMap);
inline void SetHeightSampler(TextureSamplerInfo heightSampler);
inline void SetMetallicMap(std::shared_ptr<Texture> metallicMap);
inline void SetMetallicSampler(TextureSamplerInfo metallicSampler);
inline void SetNormalMap(std::shared_ptr<Texture> normalMap);
inline void SetNormalSampler(TextureSamplerInfo normalSampler);
inline void SetRoughnessMap(std::shared_ptr<Texture> roughnessMap);
inline void SetRoughnessSampler(TextureSamplerInfo roughnessSampler);
void SetShininess(float shininess);
void SetSpecularColor(const Color& specular);
inline void SetSpecularMap(std::shared_ptr<Texture> specularMap);
inline void SetSpecularSampler(TextureSamplerInfo specularSampler);
static const std::shared_ptr<MaterialSettings>& GetSettings();
protected:
struct PbrOptionIndexes
{
std::size_t hasEmissiveMap;
std::size_t hasHeightMap;
std::size_t hasMetallicMap;
std::size_t hasNormalMap;
std::size_t hasRoughnessMap;
std::size_t hasSpecularMap;
};
struct PbrUniformOffsets
{
std::size_t ambientColor;
std::size_t shininess;
std::size_t totalSize;
std::size_t specularColor;
};
struct PbrTextureIndexes
{
std::size_t emissive;
std::size_t height;
std::size_t metallic;
std::size_t roughness;
std::size_t normal;
std::size_t specular;
};
struct PbrBuildOptions : BasicBuildOptions
{
PbrUniformOffsets pbrOffsets;
PbrOptionIndexes* pbrOptionIndexes = nullptr;
PbrTextureIndexes* pbrTextureIndexes = nullptr;
};
PbrOptionIndexes m_pbrOptionIndexes;
PbrTextureIndexes m_pbrTextureIndexes;
PbrUniformOffsets m_pbrUniformOffsets;
static MaterialSettings::Builder Build(PbrBuildOptions& options);
static std::vector<std::shared_ptr<UberShader>> BuildShaders();
static std::pair<PbrUniformOffsets, nzsl::FieldOffsets> BuildUniformOffsets();
private:
static bool Initialize();
static void Uninitialize();
static std::shared_ptr<MaterialSettings> s_pbrMaterialSettings;
static std::size_t s_pbrUniformBlockIndex;
static PbrOptionIndexes s_pbrOptionIndexes;
static PbrTextureIndexes s_pbrTextureIndexes;
static PbrUniformOffsets s_pbrUniformOffsets;
};
}
#include <Nazara/Graphics/PhysicallyBasedMaterial.inl>
#endif // NAZARA_GRAPHICS_PHYSICALLYBASEDMATERIAL_HPP

View File

@ -1,226 +0,0 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PhysicallyBasedMaterial.hpp>
#include <Nazara/Core/ErrorFlags.hpp>
#include <memory>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetEmissiveMap() const
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.emissive);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetEmissiveSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no emissive map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.emissive);
}
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetHeightMap() const
{
NazaraAssert(HasHeightMap(), "Material has no height map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.height);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetHeightSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no height map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.height);
}
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetMetallicMap() const
{
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.metallic);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetMetallicSampler() const
{
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.metallic);
}
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetNormalMap() const
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.normal);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetNormalSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no normal map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.normal);
}
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetRoughnessMap() const
{
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.roughness);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetRoughnessSampler() const
{
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.roughness);
}
inline const std::shared_ptr<Texture>& PhysicallyBasedMaterial::GetSpecularMap() const
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
return GetMaterial().GetTexture(m_pbrTextureIndexes.specular);
}
inline const TextureSamplerInfo& PhysicallyBasedMaterial::GetSpecularSampler() const
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
return GetMaterial().GetTextureSampler(m_pbrTextureIndexes.specular);
}
inline bool PhysicallyBasedMaterial::HasAmbientColor() const
{
return m_pbrUniformOffsets.ambientColor != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasEmissiveMap() const
{
return m_pbrTextureIndexes.emissive != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasHeightMap() const
{
return m_pbrTextureIndexes.height != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasMetallicMap() const
{
return m_pbrTextureIndexes.metallic != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasNormalMap() const
{
return m_pbrTextureIndexes.normal != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasRoughnessMap() const
{
return m_pbrTextureIndexes.roughness != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasShininess() const
{
return m_pbrUniformOffsets.shininess != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasSpecularColor() const
{
return m_pbrUniformOffsets.specularColor != MaterialSettings::InvalidIndex;
}
inline bool PhysicallyBasedMaterial::HasSpecularMap() const
{
return m_pbrTextureIndexes.specular != MaterialSettings::InvalidIndex;
}
inline void PhysicallyBasedMaterial::SetEmissiveMap(std::shared_ptr<Texture> emissiveMap)
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
bool hasEmissiveMap = (emissiveMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.emissive, std::move(emissiveMap));
if (m_pbrOptionIndexes.hasEmissiveMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasEmissiveMap, hasEmissiveMap);
}
inline void PhysicallyBasedMaterial::SetEmissiveSampler(TextureSamplerInfo emissiveSampler)
{
NazaraAssert(HasEmissiveMap(), "Material has no emissive map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.emissive, std::move(emissiveSampler));
}
inline void PhysicallyBasedMaterial::SetHeightMap(std::shared_ptr<Texture> heightMap)
{
NazaraAssert(HasHeightMap(), "Material has no specular map slot");
bool hasHeightMap = (heightMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.height, std::move(heightMap));
if (m_pbrOptionIndexes.hasHeightMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasHeightMap, hasHeightMap);
}
inline void PhysicallyBasedMaterial::SetHeightSampler(TextureSamplerInfo heightSampler)
{
NazaraAssert(HasHeightMap(), "Material has no height map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.height, std::move(heightSampler));
}
inline void PhysicallyBasedMaterial::SetMetallicMap(std::shared_ptr<Texture> metallicMap)
{
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
bool hasMetallicMap = (metallicMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.metallic, std::move(metallicMap));
if (m_pbrOptionIndexes.hasMetallicMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasMetallicMap, hasMetallicMap);
}
inline void PhysicallyBasedMaterial::SetMetallicSampler(TextureSamplerInfo metallicSampler)
{
NazaraAssert(HasMetallicMap(), "Material has no metallic map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.metallic, std::move(metallicSampler));
}
inline void PhysicallyBasedMaterial::SetNormalMap(std::shared_ptr<Texture> normalMap)
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
bool hasNormalMap = (normalMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.normal, std::move(normalMap));
if (m_pbrOptionIndexes.hasNormalMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasNormalMap, hasNormalMap);
}
inline void PhysicallyBasedMaterial::SetNormalSampler(TextureSamplerInfo normalSampler)
{
NazaraAssert(HasNormalMap(), "Material has no normal map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.normal, std::move(normalSampler));
}
inline void PhysicallyBasedMaterial::SetRoughnessMap(std::shared_ptr<Texture> roughnessMap)
{
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
bool hasRoughnessMap = (roughnessMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.roughness, std::move(roughnessMap));
if (m_pbrOptionIndexes.hasRoughnessMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasRoughnessMap, hasRoughnessMap);
}
inline void PhysicallyBasedMaterial::SetRoughnessSampler(TextureSamplerInfo metallicSampler)
{
NazaraAssert(HasRoughnessMap(), "Material has no roughness map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.roughness, std::move(metallicSampler));
}
inline void PhysicallyBasedMaterial::SetSpecularMap(std::shared_ptr<Texture> specularMap)
{
NazaraAssert(HasNormalMap(), "Material has no specular map slot");
bool hasSpecularMap = (specularMap != nullptr);
GetMaterial().SetTexture(m_pbrTextureIndexes.specular, std::move(specularMap));
if (m_pbrOptionIndexes.hasSpecularMap != MaterialSettings::InvalidIndex)
GetMaterial().SetOptionValue(m_pbrOptionIndexes.hasSpecularMap, hasSpecularMap);
}
inline void PhysicallyBasedMaterial::SetSpecularSampler(TextureSamplerInfo specularSampler)
{
NazaraAssert(HasSpecularMap(), "Material has no specular map slot");
GetMaterial().SetTextureSampler(m_pbrTextureIndexes.specular, std::move(specularSampler));
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,31 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PREDEFINEDMATERIALS_HPP
#define NAZARA_GRAPHICS_PREDEFINEDMATERIALS_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
namespace Nz
{
class MaterialSettings;
class NAZARA_GRAPHICS_API PredefinedMaterials
{
public:
PredefinedMaterials() = delete;
~PredefinedMaterials() = delete;
static void AddBasicSettings(MaterialSettings& settings);
static void AddPbrSettings(MaterialSettings& settings);
static void AddPhongSettings(MaterialSettings& settings);
};
}
#include <Nazara/Graphics/PredefinedMaterials.inl>
#endif // NAZARA_GRAPHICS_PREDEFINEDMATERIALS_HPP

View File

@ -2,15 +2,11 @@
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/DepthMaterial.hpp>
#include <Nazara/Graphics/PredefinedMaterials.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline const std::shared_ptr<MaterialSettings>& DepthMaterial::GetSettings()
{
return s_depthMaterialSettings;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -35,7 +35,6 @@ namespace Nz
static constexpr std::size_t MaxLightCount = 3;
static PredefinedLightData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedInstanceData
@ -45,7 +44,6 @@ namespace Nz
std::size_t worldMatrixOffset;
static PredefinedInstanceData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedSkeletalData
@ -56,7 +54,6 @@ namespace Nz
static constexpr std::size_t MaxMatricesCount = 256;
static PredefinedSkeletalData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
struct NAZARA_GRAPHICS_API PredefinedViewerData
@ -73,7 +70,6 @@ namespace Nz
std::size_t viewProjMatrixOffset;
static PredefinedViewerData GetOffsets();
static MaterialSettings::SharedUniformBlock GetUniformBlock(UInt32 bindingIndex, nzsl::ShaderStageTypeFlags shaderStages);
};
}

View File

@ -0,0 +1,43 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP
#define NAZARA_GRAPHICS_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
namespace Nz
{
class NAZARA_GRAPHICS_API OptionValuePropertyHandler : public PropertyHandler
{
public:
inline OptionValuePropertyHandler(std::string propertyName, std::string optionName);
OptionValuePropertyHandler(const OptionValuePropertyHandler&) = default;
OptionValuePropertyHandler(OptionValuePropertyHandler&&) = delete;
~OptionValuePropertyHandler() = default;
bool NeedsUpdateOnValueUpdate(std::size_t updatedPropertyIndex) const override;
void Setup(const Material& material, const ShaderReflection& reflection) override;
void Update(MaterialInstance& materialInstance) const override;
OptionValuePropertyHandler& operator=(const OptionValuePropertyHandler&) = delete;
OptionValuePropertyHandler& operator=(OptionValuePropertyHandler&&) = delete;
private:
std::size_t m_propertyIndex;
std::string m_propertyName;
std::string m_optionName;
UInt32 m_optionHash;
};
}
#include <Nazara/Graphics/PropertyHandler/OptionValuePropertyHandler.inl>
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_OPTIONVALUEPROPERTYHANDLER_HPP

View File

@ -0,0 +1,17 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PropertyHandler/OptionValuePropertyHandler.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline OptionValuePropertyHandler::OptionValuePropertyHandler(std::string propertyName, std::string optionName) :
m_propertyName(std::move(propertyName)),
m_optionName(std::move(optionName))
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,54 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PROPERTYHANDLER_PROPERTYHANDLER_HPP
#define NAZARA_GRAPHICS_PROPERTYHANDLER_PROPERTYHANDLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Core/Enums.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <NZSL/Enums.hpp>
namespace Nz
{
class Material;
class MaterialInstance;
class ShaderReflection;
class NAZARA_GRAPHICS_API PropertyHandler
{
public:
PropertyHandler() = default;
PropertyHandler(const PropertyHandler&) = delete;
PropertyHandler(PropertyHandler&&) = delete;
virtual ~PropertyHandler();
virtual bool NeedsUpdateOnTextureUpdate(std::size_t updatedTexturePropertyIndex) const;
virtual bool NeedsUpdateOnValueUpdate(std::size_t updatedValuePropertyIndex) const;
virtual void Setup(const Material& material, const ShaderReflection& reflection) = 0;
virtual void Update(MaterialInstance& materialInstance) const = 0;
PropertyHandler& operator=(const PropertyHandler&) = delete;
PropertyHandler& operator=(PropertyHandler&&) = delete;
struct SamplerData
{
std::size_t textureIndex;
};
struct UniformValue
{
std::size_t uniformBufferIndex;
std::size_t offset;
};
};
}
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.inl>
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_PROPERTYHANDLER_HPP

View File

@ -0,0 +1,13 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,48 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP
#define NAZARA_GRAPHICS_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
#include <string>
namespace Nz
{
class NAZARA_GRAPHICS_API TexturePropertyHandler : public PropertyHandler
{
public:
inline TexturePropertyHandler(std::string propertyName);
inline TexturePropertyHandler(std::string propertyName, std::string optionName);
inline TexturePropertyHandler(std::string propertyName, std::string samplerTag, std::string optionName);
TexturePropertyHandler(const TexturePropertyHandler&) = delete;
TexturePropertyHandler(TexturePropertyHandler&&) = delete;
~TexturePropertyHandler() = default;
bool NeedsUpdateOnTextureUpdate(std::size_t updatedPropertyIndex) const override;
void Setup(const Material& material, const ShaderReflection& reflection) override;
void Update(MaterialInstance& materialInstance) const override;
TexturePropertyHandler& operator=(const TexturePropertyHandler&) = delete;
TexturePropertyHandler& operator=(TexturePropertyHandler&&) = delete;
private:
std::size_t m_propertyIndex;
std::size_t m_textureIndex;
std::string m_optionName;
std::string m_propertyName;
std::string m_samplerTag;
UInt32 m_optionHash;
};
}
#include <Nazara/Graphics/PropertyHandler/TexturePropertyHandler.inl>
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_TEXTUREPROPERTYHANDLER_HPP

View File

@ -0,0 +1,31 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PropertyHandler/TexturePropertyHandler.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName) :
m_propertyName(std::move(propertyName)),
m_samplerTag(m_propertyName)
{
}
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName, std::string optionName) :
m_optionName(std::move(optionName)),
m_propertyName(std::move(propertyName)),
m_samplerTag(m_propertyName)
{
}
inline TexturePropertyHandler::TexturePropertyHandler(std::string propertyName, std::string samplerTag, std::string optionName) :
m_optionName(std::move(optionName)),
m_propertyName(std::move(propertyName)),
m_samplerTag(std::move(samplerTag))
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,47 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP
#define NAZARA_GRAPHICS_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/PropertyHandler/PropertyHandler.hpp>
namespace Nz
{
class NAZARA_GRAPHICS_API UniformValuePropertyHandler : public PropertyHandler
{
public:
inline UniformValuePropertyHandler(std::string propertyName, std::string blockTag = "Settings");
inline UniformValuePropertyHandler(std::string propertyName, std::string memberTag, std::string blockTag = "Settings");
UniformValuePropertyHandler(const UniformValuePropertyHandler&) = delete;
UniformValuePropertyHandler(UniformValuePropertyHandler&&) = delete;
~UniformValuePropertyHandler() = default;
bool NeedsUpdateOnValueUpdate(std::size_t updatedPropertyIndex) const override;
void Setup(const Material& material, const ShaderReflection& reflection) override;
void Update(MaterialInstance& materialInstance) const override;
UniformValuePropertyHandler& operator=(const UniformValuePropertyHandler&) = delete;
UniformValuePropertyHandler& operator=(UniformValuePropertyHandler&&) = delete;
private:
std::size_t m_propertyIndex;
std::size_t m_offset;
std::size_t m_size;
std::size_t m_uniformBlockIndex;
std::string m_blockTag;
std::string m_propertyName;
std::string m_memberTag;
};
}
#include <Nazara/Graphics/PropertyHandler/UniformValuePropertyHandler.inl>
#endif // NAZARA_GRAPHICS_PROPERTYHANDLER_UNIFORMVALUEPROPERTYHANDLER_HPP

View File

@ -0,0 +1,25 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/PropertyHandler/UniformValuePropertyHandler.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline UniformValuePropertyHandler::UniformValuePropertyHandler(std::string propertyName, std::string blockTag) :
m_blockTag(std::move(blockTag)),
m_propertyName(std::move(propertyName)),
m_memberTag(m_propertyName)
{
}
inline UniformValuePropertyHandler::UniformValuePropertyHandler(std::string propertyName, std::string memberTag, std::string blockTag) :
m_blockTag(std::move(blockTag)),
m_propertyName(std::move(propertyName)),
m_memberTag(std::move(memberTag))
{
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -0,0 +1,54 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_RENDERBUFFERPOOL_HPP
#define NAZARA_GRAPHICS_RENDERBUFFERPOOL_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/RenderBufferView.hpp>
#include <Nazara/Utils/Bitset.hpp>
#include <vector>
namespace Nz
{
class RenderBuffer;
class RenderDevice;
class NAZARA_GRAPHICS_API RenderBufferPool
{
public:
RenderBufferPool(std::shared_ptr<RenderDevice> renderDevice, BufferType bufferType, std::size_t bufferSize, std::size_t bufferPerBlock = 2048);
RenderBufferPool(const RenderBufferPool&) = delete;
RenderBufferPool(RenderBufferPool&&) = delete;
~RenderBufferPool() = default;
RenderBufferView Allocate(std::size_t& index);
void Free(std::size_t index);
inline UInt64 GetBufferAlignedSize() const;
inline UInt64 GetBufferPerBlock() const;
inline UInt64 GetBufferSize() const;
inline BufferType GetBufferType() const;
RenderBufferPool& operator=(const RenderBufferPool&) = delete;
RenderBufferPool& operator=(RenderBufferPool&&) = delete;
private:
UInt64 m_bufferAlignedSize;
UInt64 m_bufferPerBlock;
UInt64 m_bufferSize;
std::shared_ptr<RenderDevice> m_renderDevice;
std::vector<std::shared_ptr<RenderBuffer>> m_bufferBlocks;
Bitset<UInt64> m_availableEntries;
BufferType m_bufferType;
};
}
#include <Nazara/Graphics/RenderBufferPool.inl>
#endif // NAZARA_GRAPHICS_RENDERBUFFERPOOL_HPP

View File

@ -0,0 +1,31 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/RenderBufferPool.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline UInt64 Nz::RenderBufferPool::GetBufferAlignedSize() const
{
return m_bufferAlignedSize;
}
inline UInt64 RenderBufferPool::GetBufferPerBlock() const
{
return m_bufferPerBlock;
}
inline UInt64 RenderBufferPool::GetBufferSize() const
{
return m_bufferSize;
}
inline BufferType RenderBufferPool::GetBufferType() const
{
return m_bufferType;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -13,7 +13,7 @@
namespace Nz
{
class MaterialPass;
class MaterialInstance;
class RenderPipeline;
class Skeleton;
class VertexDeclaration;
@ -27,7 +27,7 @@ namespace Nz
inline void Clear();
inline std::size_t FetchLayerIndex(int renderLayer) const;
inline std::size_t FetchMaterialPassIndex(const MaterialPass* materialPass) const;
inline std::size_t FetchMaterialInstanceIndex(const MaterialInstance* materialInstance) const;
inline std::size_t FetchPipelineIndex(const RenderPipeline* pipeline) const;
inline std::size_t FetchSkeletonIndex(const Skeleton* skeleton) const;
inline std::size_t FetchVertexBuffer(const RenderBuffer* vertexBuffer) const;
@ -36,7 +36,7 @@ namespace Nz
inline void Finalize();
inline void RegisterLayer(int renderLayer);
inline void RegisterMaterialPass(const MaterialPass* materialPass);
inline void RegisterMaterialInstance(const MaterialInstance* materialInstance);
inline void RegisterPipeline(const RenderPipeline* pipeline);
inline void RegisterSkeleton(const Skeleton* skeleton);
inline void RegisterVertexBuffer(const RenderBuffer* vertexBuffer);
@ -45,7 +45,7 @@ namespace Nz
private:
std::set<int> m_renderLayers;
robin_hood::unordered_map<int, std::size_t> m_renderLayerRegistry;
robin_hood::unordered_map<const MaterialPass*, std::size_t> m_materialPassRegistry;
robin_hood::unordered_map<const MaterialInstance*, std::size_t> m_materialPassRegistry;
robin_hood::unordered_map<const RenderPipeline*, std::size_t> m_pipelineRegistry;
robin_hood::unordered_map<const RenderBuffer*, std::size_t> m_vertexBufferRegistry;
robin_hood::unordered_map<const Skeleton*, std::size_t> m_skeletonRegistry;

View File

@ -26,7 +26,7 @@ namespace Nz
return it->second;
}
inline std::size_t RenderQueueRegistry::FetchMaterialPassIndex(const MaterialPass* materialPass) const
inline std::size_t RenderQueueRegistry::FetchMaterialInstanceIndex(const MaterialInstance* materialPass) const
{
auto it = m_materialPassRegistry.find(materialPass);
assert(it != m_materialPassRegistry.end());
@ -78,9 +78,9 @@ namespace Nz
m_renderLayers.insert(renderLayer);
}
inline void RenderQueueRegistry::RegisterMaterialPass(const MaterialPass* materialPass)
inline void RenderQueueRegistry::RegisterMaterialInstance(const MaterialInstance* materialInstance)
{
m_materialPassRegistry.try_emplace(materialPass, m_materialPassRegistry.size());
m_materialPassRegistry.try_emplace(materialInstance, m_materialPassRegistry.size());
}
inline void RenderQueueRegistry::RegisterPipeline(const RenderPipeline* pipeline)

View File

@ -16,19 +16,19 @@
namespace Nz
{
class MaterialPass;
class MaterialInstance;
class VertexDeclaration;
class ViewerInstance;
class RenderSpriteChain : public RenderElement
{
public:
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const Recti& scissorBox);
inline RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const Recti& scissorBox);
~RenderSpriteChain() = default;
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
inline const MaterialPass& GetMaterialPass() const;
inline const MaterialInstance& GetMaterialInstance() const;
inline const RenderPipeline& GetRenderPipeline() const;
inline const Recti& GetScissorBox() const;
inline std::size_t GetSpriteCount() const;
@ -42,13 +42,14 @@ namespace Nz
static constexpr BasicRenderElement ElementType = BasicRenderElement::SpriteChain;
private:
std::shared_ptr<MaterialPass> m_materialPass;
std::shared_ptr<MaterialInstance> m_materialInstance;
std::shared_ptr<RenderPipeline> m_renderPipeline;
std::shared_ptr<VertexDeclaration> m_vertexDeclaration;
std::shared_ptr<Texture> m_textureOverlay;
std::size_t m_spriteCount;
const void* m_spriteData;
const WorldInstance& m_worldInstance;
MaterialPassFlags m_materialFlags;
Recti m_scissorBox;
int m_renderLayer;
};

View File

@ -9,15 +9,16 @@
namespace Nz
{
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const Recti& scissorBox) :
inline RenderSpriteChain::RenderSpriteChain(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, std::shared_ptr<VertexDeclaration> vertexDeclaration, std::shared_ptr<Texture> textureOverlay, std::size_t spriteCount, const void* spriteData, const Recti& scissorBox) :
RenderElement(BasicRenderElement::SpriteChain),
m_materialPass(std::move(materialPass)),
m_materialInstance(std::move(materialInstance)),
m_renderPipeline(std::move(renderPipeline)),
m_vertexDeclaration(std::move(vertexDeclaration)),
m_textureOverlay(std::move(textureOverlay)),
m_spriteCount(spriteCount),
m_spriteData(spriteData),
m_worldInstance(worldInstance),
m_materialFlags(materialFlags),
m_scissorBox(scissorBox),
m_renderLayer(renderLayer)
{
@ -27,7 +28,7 @@ namespace Nz
{
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::SortByDistance))
if (m_materialFlags.Test(MaterialPassFlag::SortByDistance))
{
UInt64 matFlags = 1;
@ -48,7 +49,7 @@ namespace Nz
else
{
UInt64 elementType = GetElementType();
UInt64 materialPassIndex = registry.FetchMaterialPassIndex(m_materialPass.get());
UInt64 materialInstanceIndex = registry.FetchMaterialInstanceIndex(m_materialInstance.get());
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
UInt64 vertexDeclarationIndex = registry.FetchVertexDeclaration(m_vertexDeclaration.get());
@ -63,18 +64,18 @@ namespace Nz
// - VertexDeclaration (8bits)
// - ?? (8bits) - Depth?
return (layerIndex & 0xFF) << 60 |
(matFlags) << 52 |
(elementType & 0xF) << 51 |
(pipelineIndex & 0xFFFF) << 35 |
(materialPassIndex & 0xFFFF) << 23 |
(vertexDeclarationIndex & 0xFF) << 7;
return (layerIndex & 0xFF) << 60 |
(matFlags) << 52 |
(elementType & 0xF) << 51 |
(pipelineIndex & 0xFFFF) << 35 |
(materialInstanceIndex & 0xFFFF) << 23 |
(vertexDeclarationIndex & 0xFF) << 7;
}
}
inline const MaterialPass& RenderSpriteChain::GetMaterialPass() const
inline const MaterialInstance& RenderSpriteChain::GetMaterialInstance() const
{
return *m_materialPass;
return *m_materialInstance;
}
inline const RenderPipeline& RenderSpriteChain::GetRenderPipeline() const
@ -115,7 +116,7 @@ namespace Nz
inline void RenderSpriteChain::Register(RenderQueueRegistry& registry) const
{
registry.RegisterLayer(m_renderLayer);
registry.RegisterMaterialPass(m_materialPass.get());
registry.RegisterMaterialInstance(m_materialInstance.get());
registry.RegisterPipeline(m_renderPipeline.get());
registry.RegisterVertexDeclaration(m_vertexDeclaration.get());
}

View File

@ -17,14 +17,14 @@
namespace Nz
{
class MaterialPass;
class MaterialInstance;
class RenderPipeline;
class ShaderBinding;
class RenderSubmesh : public RenderElement
{
public:
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox);
inline RenderSubmesh(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox);
~RenderSubmesh() = default;
inline UInt64 ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const override;
@ -32,7 +32,7 @@ namespace Nz
inline const RenderBuffer* GetIndexBuffer() const;
inline std::size_t GetIndexCount() const;
inline IndexType GetIndexType() const;
inline const MaterialPass& GetMaterialPass() const;
inline const MaterialInstance& GetMaterialInstance() const;
inline const RenderPipeline* GetRenderPipeline() const;
inline const Recti& GetScissorBox() const;
inline const SkeletonInstance* GetSkeletonInstance() const;
@ -46,12 +46,13 @@ namespace Nz
private:
std::shared_ptr<RenderBuffer> m_indexBuffer;
std::shared_ptr<RenderBuffer> m_vertexBuffer;
std::shared_ptr<MaterialPass> m_materialPass;
std::shared_ptr<MaterialInstance> m_materialInstance;
std::shared_ptr<RenderPipeline> m_renderPipeline;
std::size_t m_indexCount;
const SkeletonInstance* m_skeletonInstance;
const WorldInstance& m_worldInstance;
IndexType m_indexType;
MaterialPassFlags m_materialFlags;
Recti m_scissorBox;
int m_renderLayer;
};

View File

@ -9,16 +9,17 @@
namespace Nz
{
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialPass> materialPass, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox) :
inline RenderSubmesh::RenderSubmesh(int renderLayer, std::shared_ptr<MaterialInstance> materialInstance, MaterialPassFlags materialFlags, std::shared_ptr<RenderPipeline> renderPipeline, const WorldInstance& worldInstance, const SkeletonInstance* skeletonInstance, std::size_t indexCount, IndexType indexType, std::shared_ptr<RenderBuffer> indexBuffer, std::shared_ptr<RenderBuffer> vertexBuffer, const Recti& scissorBox) :
RenderElement(BasicRenderElement::Submesh),
m_indexBuffer(std::move(indexBuffer)),
m_vertexBuffer(std::move(vertexBuffer)),
m_materialPass(std::move(materialPass)),
m_materialInstance(std::move(materialInstance)),
m_renderPipeline(std::move(renderPipeline)),
m_indexCount(indexCount),
m_skeletonInstance(skeletonInstance),
m_worldInstance(worldInstance),
m_indexType(indexType),
m_materialFlags(materialFlags),
m_scissorBox(scissorBox),
m_renderLayer(renderLayer)
{
@ -27,8 +28,8 @@ namespace Nz
inline UInt64 RenderSubmesh::ComputeSortingScore(const Frustumf& frustum, const RenderQueueRegistry& registry) const
{
UInt64 layerIndex = registry.FetchLayerIndex(m_renderLayer);
if (m_materialPass->IsFlagEnabled(MaterialPassFlag::SortByDistance))
if (m_materialFlags.Test(MaterialPassFlag::SortByDistance))
{
UInt64 matFlags = 1;
@ -48,7 +49,7 @@ namespace Nz
else
{
UInt64 elementType = GetElementType();
UInt64 materialPassIndex = registry.FetchMaterialPassIndex(m_materialPass.get());
UInt64 materialInstanceIndex = registry.FetchMaterialInstanceIndex(m_materialInstance.get());
UInt64 pipelineIndex = registry.FetchPipelineIndex(m_renderPipeline.get());
UInt64 vertexBufferIndex = registry.FetchVertexBuffer(m_vertexBuffer.get());
@ -67,12 +68,12 @@ namespace Nz
// - VertexBuffer (8bits)
// - Skeleton (8bits)
return (layerIndex & 0xFF) << 60 |
(matFlags) << 52 |
(elementType & 0xF) << 51 |
(pipelineIndex & 0xFFFF) << 35 |
(materialPassIndex & 0xFFFF) << 23 |
(vertexBufferIndex & 0xFF) << 7 |
return (layerIndex & 0xFF) << 60 |
(matFlags) << 52 |
(elementType & 0xF) << 51 |
(pipelineIndex & 0xFFFF) << 35 |
(materialInstanceIndex & 0xFFFF) << 23 |
(vertexBufferIndex & 0xFF) << 7 |
(skeletonIndex & 0xFF);
}
}
@ -92,9 +93,9 @@ namespace Nz
return m_indexType;
}
inline const MaterialPass& RenderSubmesh::GetMaterialPass() const
inline const MaterialInstance& RenderSubmesh::GetMaterialInstance() const
{
return *m_materialPass;
return *m_materialInstance;
}
inline const RenderPipeline* RenderSubmesh::GetRenderPipeline() const
@ -125,7 +126,7 @@ namespace Nz
inline void RenderSubmesh::Register(RenderQueueRegistry& registry) const
{
registry.RegisterLayer(m_renderLayer);
registry.RegisterMaterialPass(m_materialPass.get());
registry.RegisterMaterialInstance(m_materialInstance.get());
registry.RegisterPipeline(m_renderPipeline.get());
registry.RegisterVertexBuffer(m_vertexBuffer.get());
if (m_skeletonInstance)

View File

@ -0,0 +1,108 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_SHADERREFLECTION_HPP
#define NAZARA_GRAPHICS_SHADERREFLECTION_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <NZSL/Ast/Module.hpp>
#include <NZSL/Ast/RecursiveVisitor.hpp>
#include <NZSL/Math/FieldOffsets.hpp>
#include <unordered_map>
namespace Nz
{
class NAZARA_GRAPHICS_API ShaderReflection : nzsl::Ast::RecursiveVisitor
{
public:
struct ExternalBlockData;
struct OptionData;
struct StructData;
ShaderReflection() = default;
ShaderReflection(const ShaderReflection&) = delete;
ShaderReflection(ShaderReflection&&) = delete;
~ShaderReflection() = default;
inline const RenderPipelineLayoutInfo& GetPipelineLayoutInfo() const;
inline const ExternalBlockData* GetExternalBlockByTag(const std::string& tag) const;
inline const OptionData* GetOptionByName(const std::string& optionName) const;
inline const StructData* GetStructByIndex(std::size_t structIndex) const;
void Reflect(nzsl::Ast::Module& module);
ShaderReflection& operator=(const ShaderReflection&) = delete;
ShaderReflection& operator=(ShaderReflection&&) = delete;
struct ExternalData
{
UInt32 bindingSet;
UInt32 bindingIndex;
};
struct ExternalStorageBlock : ExternalData
{
std::size_t structIndex;
};
struct ExternalTexture : ExternalData
{
nzsl::ImageType imageType;
nzsl::Ast::PrimitiveType sampledType;
};
struct ExternalUniformBlock : ExternalData
{
std::size_t structIndex;
};
struct ExternalBlockData
{
std::unordered_map<std::string /*tag*/, ExternalStorageBlock> storageBlocks;
std::unordered_map<std::string /*tag*/, ExternalTexture> samplers;
std::unordered_map<std::string /*tag*/, ExternalUniformBlock> uniformBlocks;
};
struct OptionData
{
nzsl::Ast::ExpressionType type;
UInt32 hash;
};
struct StructMemberData
{
std::size_t offset;
std::size_t size;
nzsl::Ast::ExpressionType type;
};
struct StructData
{
StructData(nzsl::StructLayout layout) : fieldOffsets(layout) {}
std::unordered_map<std::string /*tag*/, StructMemberData> members;
nzsl::FieldOffsets fieldOffsets;
};
private:
void Visit(nzsl::Ast::ConditionalStatement& node) override;
void Visit(nzsl::Ast::DeclareExternalStatement& node) override;
void Visit(nzsl::Ast::DeclareOptionStatement& node) override;
void Visit(nzsl::Ast::DeclareStructStatement& node) override;
std::unordered_map<std::string /*tag*/, ExternalBlockData> m_externalBlocks;
std::unordered_map<std::string /*name*/, OptionData> m_options;
std::unordered_map<std::size_t /*structIndex*/, StructData> m_structs;
RenderPipelineLayoutInfo m_pipelineLayoutInfo;
bool m_isConditional;
};
}
#include <Nazara/Graphics/ShaderReflection.inl>
#endif // NAZARA_GRAPHICS_SHADERREFLECTION_HPP

View File

@ -0,0 +1,43 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/ShaderReflection.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
inline const RenderPipelineLayoutInfo& ShaderReflection::GetPipelineLayoutInfo() const
{
return m_pipelineLayoutInfo;
}
inline auto ShaderReflection::GetExternalBlockByTag(const std::string& tag) const -> const ExternalBlockData*
{
auto it = m_externalBlocks.find(tag);
if (it == m_externalBlocks.end())
return nullptr;
return &it->second;
}
inline auto ShaderReflection::GetOptionByName(const std::string& optionName) const -> const OptionData*
{
auto it = m_options.find(optionName);
if (it == m_options.end())
return nullptr;
return &it->second;
}
inline auto ShaderReflection::GetStructByIndex(std::size_t structIndex) const -> const StructData*
{
auto it = m_structs.find(structIndex);
if (it == m_structs.end())
return nullptr;
return &it->second;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <Nazara/Utility/Skeleton.hpp>
@ -23,7 +24,7 @@ namespace Nz
using SkeletonInstancePtr = std::shared_ptr<SkeletonInstance>;
class NAZARA_GRAPHICS_API SkeletonInstance
class NAZARA_GRAPHICS_API SkeletonInstance : public TransferInterface
{
public:
SkeletonInstance(std::shared_ptr<const Skeleton> skeleton);
@ -35,7 +36,7 @@ namespace Nz
inline const std::shared_ptr<RenderBuffer>& GetSkeletalBuffer() const;
inline const std::shared_ptr<const Skeleton>& GetSkeleton() const;
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
SkeletonInstance& operator=(const SkeletonInstance&) = delete;
SkeletonInstance& operator=(SkeletonInstance&& skeletonInstance) noexcept;

View File

@ -22,7 +22,7 @@ namespace Nz
public:
struct Corner;
SlicedSprite(std::shared_ptr<Material> material);
SlicedSprite(std::shared_ptr<MaterialInstance> material);
SlicedSprite(const SlicedSprite&) = delete;
SlicedSprite(SlicedSprite&&) noexcept = default;
~SlicedSprite() = default;
@ -31,7 +31,7 @@ namespace Nz
inline const Color& GetColor() const;
inline const Corner& GetBottomRightCorner() const;
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override;
inline const Corner& GetTopLeftCorner() const;
inline const Rectf& GetTextureCoords() const;
@ -41,7 +41,7 @@ namespace Nz
inline void SetCorners(const Corner& topLeftCorner, const Corner& bottomRightCorner);
inline void SetCornersSize(const Vector2f& topLeftSize, const Vector2f& bottomRightSize);
inline void SetCornersTextureCoords(const Vector2f& topLeftTextureCoords, const Vector2f& bottomRightTextureCoords);
inline void SetMaterial(std::shared_ptr<Material> material);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetSize(const Vector2f& size);
inline void SetTextureCoords(const Rectf& textureCoords);
inline void SetTextureRect(const Rectf& textureRect);
@ -59,7 +59,7 @@ namespace Nz
void UpdateVertices();
std::array<VertexStruct_XYZ_Color_UV, 4 * 9> m_vertices;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_material;
std::size_t m_spriteCount;
Color m_color;
Corner m_topLeftCorner;

View File

@ -59,7 +59,7 @@ namespace Nz
UpdateVertices();
}
inline void SlicedSprite::SetMaterial(std::shared_ptr<Material> material)
inline void SlicedSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
{
assert(material);

View File

@ -20,7 +20,7 @@ namespace Nz
class NAZARA_GRAPHICS_API Sprite : public InstancedRenderable
{
public:
Sprite(std::shared_ptr<Material> material);
Sprite(std::shared_ptr<MaterialInstance> material);
Sprite(const Sprite&) = delete;
Sprite(Sprite&&) noexcept = default;
~Sprite() = default;
@ -29,7 +29,7 @@ namespace Nz
inline const Color& GetColor() const;
inline const Color& GetCornerColor(RectCorner corner) const;
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override;
inline const Vector3f& GetOrigin() const;
inline const Vector2f& GetSize() const;
@ -38,7 +38,7 @@ namespace Nz
inline void SetColor(const Color& color);
inline void SetCornerColor(RectCorner corner, const Color& color);
inline void SetMaterial(std::shared_ptr<Material> material);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetOrigin(const Vector3f& origin);
inline void SetSize(const Vector2f& size);
inline void SetTextureCoords(const Rectf& textureCoords);
@ -52,7 +52,7 @@ namespace Nz
std::array<Color, RectCornerCount> m_cornerColor;
std::array<VertexStruct_XYZ_Color_UV, 4> m_vertices;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_material;
Color m_color;
Rectf m_textureCoords;
Vector2f m_size;

View File

@ -47,7 +47,7 @@ namespace Nz
UpdateVertices();
}
inline void Sprite::SetMaterial(std::shared_ptr<Material> material)
inline void Sprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
{
assert(material);

View File

@ -19,7 +19,6 @@
namespace Nz
{
class MaterialPass;
class RenderDevice;
class RenderPipeline;
class ShaderBinding;
@ -85,7 +84,7 @@ namespace Nz
UInt8* currentAllocationMemPtr = nullptr;
const VertexDeclaration* currentVertexDeclaration = nullptr;
RenderBuffer* currentVertexBuffer = nullptr;
const MaterialPass* currentMaterialPass = nullptr;
const MaterialInstance* currentMaterialInstance = nullptr;
const RenderPipeline* currentPipeline = nullptr;
const ShaderBinding* currentShaderBinding = nullptr;
const Texture* currentTextureOverlay = nullptr;

View File

@ -23,7 +23,7 @@ namespace Nz
class NAZARA_GRAPHICS_API TextSprite : public InstancedRenderable
{
public:
TextSprite(std::shared_ptr<Material> material);
TextSprite(std::shared_ptr<MaterialInstance> material = {});
TextSprite(const TextSprite&) = delete;
TextSprite(TextSprite&&) noexcept = default;
~TextSprite() = default;
@ -32,10 +32,10 @@ namespace Nz
inline void Clear();
const std::shared_ptr<Material>& GetMaterial(std::size_t i = 0) const override;
const std::shared_ptr<MaterialInstance>& GetMaterial(std::size_t i = 0) const override;
std::size_t GetMaterialCount() const override;
inline void SetMaterial(std::shared_ptr<Material> material);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
void Update(const AbstractTextDrawer& drawer, float scale = 1.f);
@ -92,7 +92,7 @@ namespace Nz
std::unordered_map<const AbstractAtlas*, AtlasSlots> m_atlases;
mutable std::unordered_map<RenderKey, RenderIndices, HashRenderKey> m_renderInfos;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_material;
std::vector<RenderData> m_data;
std::vector<VertexStruct_XYZ_Color_UV> m_vertices;
Recti m_scissorBox;

View File

@ -15,7 +15,7 @@ namespace Nz
OnElementInvalidated(this);
}
inline void TextSprite::SetMaterial(std::shared_ptr<Material> material)
inline void TextSprite::SetMaterial(std::shared_ptr<MaterialInstance> material)
{
assert(material);

View File

@ -0,0 +1,38 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_GRAPHICS_TRANSFERINTERFACE_HPP
#define NAZARA_GRAPHICS_TRANSFERINTERFACE_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Utils/Signal.hpp>
namespace Nz
{
class CommandBufferBuilder;
class RenderFrame;
class NAZARA_GRAPHICS_API TransferInterface
{
public:
TransferInterface() = default;
TransferInterface(const TransferInterface&) = default;
TransferInterface(TransferInterface&&) = default;
virtual ~TransferInterface();
virtual void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) = 0;
TransferInterface& operator=(const TransferInterface&) = default;
TransferInterface& operator=(TransferInterface&&) = default;
NazaraSignal(OnTransferRequired, TransferInterface* /*transfer*/);
};
}
#include <Nazara/Graphics/TransferInterface.inl>
#endif // NAZARA_GRAPHICS_TRANSFERINTERFACE_HPP

View File

@ -0,0 +1,12 @@
// Copyright (C) 2022 Jérôme "Lynix" Leclercq (lynix680@gmail.com)
// This file is part of the "Nazara Engine - Graphics module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Graphics/Debug.hpp>
namespace Nz
{
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <memory>
@ -20,7 +21,7 @@ namespace Nz
class RenderBuffer;
class UploadPool;
class NAZARA_GRAPHICS_API ViewerInstance
class NAZARA_GRAPHICS_API ViewerInstance : public TransferInterface
{
public:
ViewerInstance();
@ -39,7 +40,8 @@ namespace Nz
inline std::shared_ptr<RenderBuffer>& GetViewerBuffer();
inline const std::shared_ptr<RenderBuffer>& GetViewerBuffer() const;
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
inline void UpdateEyePosition(const Vector3f& eyePosition);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix);
inline void UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix);
@ -54,6 +56,8 @@ namespace Nz
ViewerInstance& operator=(ViewerInstance&&) noexcept = default;
private:
inline void InvalidateData();
std::shared_ptr<RenderBuffer> m_viewerDataBuffer;
Matrix4f m_invProjectionMatrix;
Matrix4f m_invViewProjMatrix;

View File

@ -61,7 +61,8 @@ namespace Nz
inline void ViewerInstance::UpdateEyePosition(const Vector3f& eyePosition)
{
m_eyePosition = eyePosition;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix)
@ -73,7 +74,7 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateProjectionMatrix(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix)
@ -84,7 +85,7 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& viewMatrix)
@ -100,7 +101,7 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
@ -113,7 +114,7 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateProjViewMatrices(const Matrix4f& projectionMatrix, const Matrix4f& invProjectionMatrix, const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix, const Matrix4f& viewProjMatrix, const Matrix4f& invViewProjMatrix)
@ -126,14 +127,14 @@ namespace Nz
m_viewProjMatrix = viewProjMatrix;
m_invViewProjMatrix = invViewProjMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateTargetSize(const Vector2f& targetSize)
{
m_targetSize = targetSize;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix)
@ -145,7 +146,7 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
m_dataInvalidated = true;
InvalidateData();
}
inline void ViewerInstance::UpdateViewMatrix(const Matrix4f& viewMatrix, const Matrix4f& invViewMatrix)
@ -156,7 +157,13 @@ namespace Nz
m_viewProjMatrix = m_viewMatrix * m_projectionMatrix;
m_invViewProjMatrix = m_invProjectionMatrix * m_invViewMatrix;
InvalidateData();
}
inline void ViewerInstance::InvalidateData()
{
m_dataInvalidated = true;
OnTransferRequired(this);
}
}

View File

@ -9,6 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/TransferInterface.hpp>
#include <Nazara/Math/Matrix4.hpp>
#include <Nazara/Renderer/ShaderBinding.hpp>
#include <memory>
@ -22,7 +23,7 @@ namespace Nz
using WorldInstancePtr = std::shared_ptr<WorldInstance>;
class NAZARA_GRAPHICS_API WorldInstance
class NAZARA_GRAPHICS_API WorldInstance : public TransferInterface
{
public:
WorldInstance();
@ -35,7 +36,8 @@ namespace Nz
inline const Matrix4f& GetInvWorldMatrix() const;
inline const Matrix4f& GetWorldMatrix() const;
void UpdateBuffers(UploadPool& uploadPool, CommandBufferBuilder& builder);
void OnTransfer(RenderFrame& renderFrame, CommandBufferBuilder& builder) override;
inline void UpdateWorldMatrix(const Matrix4f& worldMatrix);
inline void UpdateWorldMatrix(const Matrix4f& worldMatrix, const Matrix4f& invWorldMatrix);
@ -43,6 +45,8 @@ namespace Nz
WorldInstance& operator=(WorldInstance&&) noexcept = default;
private:
inline void InvalidateData();
std::shared_ptr<RenderBuffer> m_instanceDataBuffer;
Matrix4f m_invWorldMatrix;
Matrix4f m_worldMatrix;

View File

@ -34,14 +34,21 @@ namespace Nz
if (!m_worldMatrix.GetInverseTransform(&m_invWorldMatrix))
NazaraError("failed to inverse world matrix");
m_dataInvalided = true;
InvalidateData();
}
inline void WorldInstance::UpdateWorldMatrix(const Matrix4f& worldMatrix, const Matrix4f& invWorldMatrix)
{
m_worldMatrix = worldMatrix;
m_invWorldMatrix = invWorldMatrix;
InvalidateData();
}
void WorldInstance::InvalidateData()
{
m_dataInvalided = true;
OnTransferRequired(this);
}
}

View File

@ -19,7 +19,7 @@ namespace Nz
class RenderPass;
class Texture;
class NAZARA_OPENGLRENDERER_API OpenGLFboFramebuffer : public OpenGLFramebuffer
class NAZARA_OPENGLRENDERER_API OpenGLFboFramebuffer final : public OpenGLFramebuffer
{
public:
OpenGLFboFramebuffer(OpenGLDevice& device, const std::vector<std::shared_ptr<Texture>>& attachments);
@ -31,12 +31,15 @@ namespace Nz
std::size_t GetColorBufferCount() const override;
const Vector2ui& GetSize() const override;
OpenGLFboFramebuffer& operator=(const OpenGLFboFramebuffer&) = delete;
OpenGLFboFramebuffer& operator=(OpenGLFboFramebuffer&&) = delete;
private:
GL::Framebuffer m_framebuffer;
std::size_t m_colorAttachmentCount;
Vector2ui m_size;
};
}

View File

@ -8,6 +8,7 @@
#define NAZARA_OPENGLRENDERER_OPENGLFRAMEBUFFER_HPP
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Math/Vector2.hpp>
#include <Nazara/OpenGLRenderer/Config.hpp>
#include <Nazara/Renderer/Framebuffer.hpp>
@ -26,6 +27,8 @@ namespace Nz
virtual std::size_t GetColorBufferCount() const = 0;
virtual const Vector2ui& GetSize() const = 0;
OpenGLFramebuffer& operator=(const OpenGLFramebuffer&) = delete;
OpenGLFramebuffer& operator=(OpenGLFramebuffer&&) noexcept = default;
};

View File

@ -22,7 +22,7 @@ namespace Nz
{
class RenderWindow;
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow : public RenderWindowImpl
class NAZARA_OPENGLRENDERER_API OpenGLRenderWindow final : public RenderWindowImpl
{
public:
OpenGLRenderWindow(RenderWindow& owner);

View File

@ -26,6 +26,8 @@ namespace Nz
std::size_t GetColorBufferCount() const override;
const Vector2ui& GetSize() const override;
OpenGLWindowFramebuffer& operator=(const OpenGLWindowFramebuffer&) = delete;
OpenGLWindowFramebuffer& operator=(OpenGLWindowFramebuffer&&) = delete;

View File

@ -111,10 +111,10 @@ namespace Nz::GL
inline void Context::ResetColorWriteMasks() const
{
if (!m_state.renderStates.colorWrite)
if (m_state.renderStates.colorWriteMask != ColorComponentAll)
{
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
m_state.renderStates.colorWrite = true;
m_state.renderStates.colorWriteMask = ColorComponentAll;
}
}

View File

@ -23,6 +23,9 @@
typedef void (GL_APIENTRYP PFNGLDRAWBUFFERPROC) (GLenum buf);
typedef void (GL_APIENTRYP PFNGLPOLYGONMODEPROC) (GLenum face, GLenum mode);
// Depth clamp (OpenGL 3.2)
#define GL_DEPTH_CLAMP 0x864F
// Clip control (OpenGL 4.5)
#define GL_LOWER_LEFT 0x8CA1
#define GL_UPPER_LEFT 0x8CA2

View File

@ -24,6 +24,24 @@ namespace Nz
Store
};
enum class ColorComponent
{
Red,
Green,
Blue,
Alpha
};
template<>
struct EnumAsFlags<ColorComponent>
{
static constexpr ColorComponent max = ColorComponent::Alpha;
};
using ColorComponentMask = Flags<ColorComponent>;
constexpr ColorComponentMask ColorComponentAll = ColorComponent::Red | ColorComponent::Green | ColorComponent::Blue | ColorComponent::Alpha;
enum class FramebufferType
{
Texture,

View File

@ -23,6 +23,7 @@ namespace Nz
struct RenderDeviceLimits
{
UInt64 minStorageBufferOffsetAlignment;
UInt64 minUniformBufferOffsetAlignment;
UInt64 maxStorageBufferSize;
UInt64 maxUniformBufferSize;

View File

@ -19,6 +19,7 @@ namespace Nz
struct RenderStates
{
ColorComponentMask colorWriteMask = ColorComponentAll;
FaceFilling faceFilling = FaceFilling::Fill;
FaceSide cullingSide = FaceSide::Back;
FrontFace frontFace = FrontFace::CounterClockwise;
@ -47,7 +48,6 @@ namespace Nz
} stencilBack, stencilFront;
bool blending = false;
bool colorWrite = true;
bool depthBuffer = false;
bool depthClamp = false;
bool depthWrite = true;

View File

@ -17,7 +17,6 @@ namespace Nz
#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false
NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(colorWrite);
NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(depthClamp);
NazaraRenderStateBoolMember(faceCulling);
@ -27,6 +26,7 @@ namespace Nz
if (lhs.depthBuffer)
NazaraRenderStateBoolMember(depthWrite);
NazaraRenderStateMember(colorWriteMask);
NazaraRenderStateMember(faceFilling);
if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
@ -91,10 +91,10 @@ namespace std
#define NazaraRenderStateBoolDep(dependency, member) parameterHash |= ((pipelineInfo.dependency && pipelineInfo.member) ? 1U : 0U) << (parameterIndex++)
#define NazaraRenderStateEnum(member) Nz::HashCombine(seed, static_cast<Nz::UInt8>(pipelineInfo.member))
#define NazaraRenderStateFloat(member, maxDiff) Nz::HashCombine(seed, std::floor(pipelineInfo.member / maxDiff) * maxDiff)
#define NazaraRenderStateUInt8(member) Nz::HashCombine(seed, pipelineInfo.member)
#define NazaraRenderStateUInt32(member) Nz::HashCombine(seed, pipelineInfo.member)
NazaraRenderStateBool(blending);
NazaraRenderStateBool(colorWrite);
NazaraRenderStateBool(depthBuffer);
NazaraRenderStateBool(depthClamp);
NazaraRenderStateBool(faceCulling);
@ -103,6 +103,7 @@ namespace std
NazaraRenderStateBoolDep(depthBuffer, depthWrite);
NazaraRenderStateUInt8(colorWriteMask);
NazaraRenderStateEnum(faceFilling);
if (pipelineInfo.blending) //< we don't care about blending state if blending isn't enabled

View File

@ -62,7 +62,7 @@ namespace Nz
struct Binding
{
std::size_t bindingIndex;
UInt32 bindingIndex;
std::variant<StorageBufferBinding, TextureBinding, UniformBufferBinding> content;
};

View File

@ -16,7 +16,6 @@
namespace Nz
{
class AbstractTextDrawer;
class MaterialPass;
class NAZARA_WIDGETS_API ButtonWidget : public BaseWidget
{

View File

@ -16,8 +16,6 @@
namespace Nz
{
class MaterialPass;
class NAZARA_WIDGETS_API CheckboxWidget : public BaseWidget
{
public:

View File

@ -34,20 +34,20 @@ namespace Nz
DefaultWidgetTheme& operator=(DefaultWidgetTheme&&) = default;
private:
std::shared_ptr<Material> m_buttonMaterial;
std::shared_ptr<Material> m_buttonHoveredMaterial;
std::shared_ptr<Material> m_buttonPressedHoveredMaterial;
std::shared_ptr<Material> m_buttonPressedMaterial;
std::shared_ptr<Material> m_checkboxBackgroundMaterial;
std::shared_ptr<Material> m_checkboxBackgroundHoveredMaterial;
std::shared_ptr<Material> m_checkboxCheckMaterial;
std::shared_ptr<Material> m_checkboxTristateMaterial;
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_scrollbarBackgroundHorizontalMaterial;
std::shared_ptr<Material> m_scrollbarBackgroundVerticalMaterial;
std::shared_ptr<Material> m_scrollbarButtonMaterial;
std::shared_ptr<Material> m_scrollbarButtonHoveredMaterial;
std::shared_ptr<Material> m_scrollbarButtonGrabbedMaterial;
std::shared_ptr<MaterialInstance> m_buttonMaterial;
std::shared_ptr<MaterialInstance> m_buttonHoveredMaterial;
std::shared_ptr<MaterialInstance> m_buttonPressedHoveredMaterial;
std::shared_ptr<MaterialInstance> m_buttonPressedMaterial;
std::shared_ptr<MaterialInstance> m_checkboxBackgroundMaterial;
std::shared_ptr<MaterialInstance> m_checkboxBackgroundHoveredMaterial;
std::shared_ptr<MaterialInstance> m_checkboxCheckMaterial;
std::shared_ptr<MaterialInstance> m_checkboxTristateMaterial;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_scrollbarBackgroundHorizontalMaterial;
std::shared_ptr<MaterialInstance> m_scrollbarBackgroundVerticalMaterial;
std::shared_ptr<MaterialInstance> m_scrollbarButtonMaterial;
std::shared_ptr<MaterialInstance> m_scrollbarButtonHoveredMaterial;
std::shared_ptr<MaterialInstance> m_scrollbarButtonGrabbedMaterial;
};
}

View File

@ -16,14 +16,13 @@
namespace Nz
{
class AbstractTextDrawer;
class MaterialPass;
class NAZARA_WIDGETS_API ImageButtonWidget : public BaseWidget
{
public:
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material);
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, float cornerSize, float cornerTexCoords);
ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial, std::shared_ptr<Material> pressedMaterial, float cornerSize, float cornerTexCoords);
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material);
inline ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, float cornerSize, float cornerTexCoords);
ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, std::shared_ptr<MaterialInstance> hoveredMaterial, std::shared_ptr<MaterialInstance> pressedMaterial, float cornerSize, float cornerTexCoords);
ImageButtonWidget(const ImageButtonWidget&) = delete;
ImageButtonWidget(ImageButtonWidget&&) = default;
~ImageButtonWidget() = default;
@ -31,16 +30,16 @@ namespace Nz
inline const Color& GetColor() const;
inline float GetCornerSize() const;
inline float GetCornerTexCoords() const;
inline const std::shared_ptr<Material>& GetHoveredMaterial() const;
inline const std::shared_ptr<Material>& GetMaterial() const;
inline const std::shared_ptr<Material>& GetPressedMaterial() const;
inline const std::shared_ptr<MaterialInstance>& GetHoveredMaterial() const;
inline const std::shared_ptr<MaterialInstance>& GetMaterial() const;
inline const std::shared_ptr<MaterialInstance>& GetPressedMaterial() const;
inline const Rectf& GetTextureCoords() const;
inline void SetColor(const Color& color);
inline void SetCorner(float size, float texcoords);
inline void SetHoveredMaterial(std::shared_ptr<Material> material);
inline void SetMaterial(std::shared_ptr<Material> material);
inline void SetPressedMaterial(std::shared_ptr<Material> material);
inline void SetHoveredMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetPressedMaterial(std::shared_ptr<MaterialInstance> material);
inline void SetTextureCoords(const Rectf& coords);
ImageButtonWidget& operator=(const ImageButtonWidget&) = delete;
@ -61,9 +60,9 @@ namespace Nz
void UpdatePreferredSize();
std::unique_ptr<ImageButtonWidgetStyle> m_style;
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<Material> m_pressedMaterial;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<MaterialInstance> m_pressedMaterial;
Color m_color;
Rectf m_textureCoords;
float m_cornerSize;

View File

@ -7,12 +7,12 @@
namespace Nz
{
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material) :
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material) :
ImageButtonWidget(parent, std::move(material), {}, {}, 0.f, 0.f)
{
}
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<Material> material, float cornerSize, float cornerTexCoords) :
inline ImageButtonWidget::ImageButtonWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material, float cornerSize, float cornerTexCoords) :
ImageButtonWidget(parent, std::move(material), {}, {}, cornerSize, cornerTexCoords)
{
}
@ -32,17 +32,17 @@ namespace Nz
return m_cornerTexCoords;
}
inline const std::shared_ptr<Material>& ImageButtonWidget::GetHoveredMaterial() const
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetHoveredMaterial() const
{
return m_hoveredMaterial;
}
inline const std::shared_ptr<Material>& ImageButtonWidget::GetMaterial() const
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetMaterial() const
{
return m_material;
}
inline const std::shared_ptr<Material>& ImageButtonWidget::GetPressedMaterial() const
inline const std::shared_ptr<MaterialInstance>& ImageButtonWidget::GetPressedMaterial() const
{
return m_pressedMaterial;
}
@ -67,14 +67,14 @@ namespace Nz
m_style->OnUpdate();
}
inline void ImageButtonWidget::SetHoveredMaterial(std::shared_ptr<Material> material)
inline void ImageButtonWidget::SetHoveredMaterial(std::shared_ptr<MaterialInstance> material)
{
m_hoveredMaterial = std::move(material);
m_style->OnUpdate();
}
inline void ImageButtonWidget::SetMaterial(std::shared_ptr<Material> material)
inline void ImageButtonWidget::SetMaterial(std::shared_ptr<MaterialInstance> material)
{
m_material = std::move(material);
UpdatePreferredSize();
@ -82,7 +82,7 @@ namespace Nz
m_style->OnUpdate();
}
inline void ImageButtonWidget::SetPressedMaterial(std::shared_ptr<Material> material)
inline void ImageButtonWidget::SetPressedMaterial(std::shared_ptr<MaterialInstance> material)
{
m_pressedMaterial = std::move(material);

View File

@ -17,17 +17,17 @@ namespace Nz
class NAZARA_WIDGETS_API ImageWidget : public BaseWidget
{
public:
ImageWidget(BaseWidget* parent, std::shared_ptr<Material> material);
ImageWidget(BaseWidget* parent, std::shared_ptr<MaterialInstance> material);
ImageWidget(const ImageWidget&) = delete;
ImageWidget(ImageWidget&&) = default;
~ImageWidget() = default;
inline const Color& GetColor() const;
inline const std::shared_ptr<Material>& GetMaterial() const;
inline const std::shared_ptr<MaterialInstance>& GetMaterial() const;
inline const Rectf& GetTextureCoords() const;
inline void SetColor(const Color& color);
inline void SetMaterial(const std::shared_ptr<Material>& texture);
inline void SetMaterial(const std::shared_ptr<MaterialInstance>& texture);
inline void SetTextureCoords(const Rectf& coords);
inline void SetTextureRect(const Rectf& rect);

View File

@ -12,7 +12,7 @@ namespace Nz
return m_sprite->GetColor();
}
inline const std::shared_ptr<Material>& ImageWidget::GetMaterial() const
inline const std::shared_ptr<MaterialInstance>& ImageWidget::GetMaterial() const
{
return m_sprite->GetMaterial();
}
@ -27,7 +27,7 @@ namespace Nz
m_sprite->SetColor(color);
}
inline void ImageWidget::SetMaterial(const std::shared_ptr<Material>& texture)
inline void ImageWidget::SetMaterial(const std::shared_ptr<MaterialInstance>& texture)
{
m_sprite->SetMaterial(texture);
UpdatePreferredSize();

View File

@ -16,7 +16,6 @@
namespace Nz
{
class AbstractTextDrawer;
class MaterialPass;
class NAZARA_WIDGETS_API ScrollbarButtonWidget : public BaseWidget
{

View File

@ -40,10 +40,10 @@ namespace Nz
struct StyleConfig
{
std::shared_ptr<Material> hoveredMaterial;
std::shared_ptr<Material> material;
std::shared_ptr<Material> pressedMaterial;
std::shared_ptr<Material> pressedHoveredMaterial;
std::shared_ptr<MaterialInstance> hoveredMaterial;
std::shared_ptr<MaterialInstance> material;
std::shared_ptr<MaterialInstance> pressedMaterial;
std::shared_ptr<MaterialInstance> pressedHoveredMaterial;
float cornerSize;
float cornerTexCoords;
};
@ -52,10 +52,10 @@ namespace Nz
virtual void UpdateMaterial(bool hovered, bool pressed);
private:
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<Material> m_pressedMaterial;
std::shared_ptr<Material> m_pressedHoveredMaterial;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<MaterialInstance> m_pressedMaterial;
std::shared_ptr<MaterialInstance> m_pressedHoveredMaterial;
std::shared_ptr<SlicedSprite> m_sprite;
std::shared_ptr<TextSprite> m_textSprite;
entt::entity m_spriteEntity;
@ -87,10 +87,10 @@ namespace Nz
struct StyleConfig
{
std::shared_ptr<Material> backgroundMaterial;
std::shared_ptr<Material> backgroundHoveredMaterial;
std::shared_ptr<Material> checkMaterial;
std::shared_ptr<Material> tristateMaterial;
std::shared_ptr<MaterialInstance> backgroundMaterial;
std::shared_ptr<MaterialInstance> backgroundHoveredMaterial;
std::shared_ptr<MaterialInstance> checkMaterial;
std::shared_ptr<MaterialInstance> tristateMaterial;
float backgroundCornerSize;
float backgroundCornerTexCoords;
};
@ -99,10 +99,10 @@ namespace Nz
virtual void UpdateMaterial(bool hovered);
private:
std::shared_ptr<Material> m_checkMaterial;
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<Material> m_tristateMaterial;
std::shared_ptr<MaterialInstance> m_checkMaterial;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<MaterialInstance> m_tristateMaterial;
std::shared_ptr<Sprite> m_checkSprite;
std::shared_ptr<SlicedSprite> m_backgroundSprite;
entt::entity m_backgroundEntity;
@ -135,7 +135,7 @@ namespace Nz
struct StyleConfig
{
std::shared_ptr<Material> hoveredMaterial;
std::shared_ptr<MaterialInstance> hoveredMaterial;
float hoveredCornerSize;
float hoveredCornerTexCoords;
};
@ -154,7 +154,7 @@ namespace Nz
class NAZARA_WIDGETS_API SimpleLabelWidgetStyle : public LabelWidgetStyle
{
public:
SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<Material> material, std::shared_ptr<Material> hoveredMaterial = {});
SimpleLabelWidgetStyle(LabelWidget* labelWidget, std::shared_ptr<MaterialInstance> material, std::shared_ptr<MaterialInstance> hoveredMaterial = {});
SimpleLabelWidgetStyle(const SimpleLabelWidgetStyle&) = delete;
SimpleLabelWidgetStyle(SimpleLabelWidgetStyle&&) = default;
~SimpleLabelWidgetStyle() = default;
@ -174,8 +174,8 @@ namespace Nz
virtual void UpdateMaterial(bool hovered);
private:
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<TextSprite> m_textSprite;
entt::entity m_entity;
};
@ -196,8 +196,8 @@ namespace Nz
SimpleScrollAreaWidgetStyle& operator=(SimpleScrollAreaWidgetStyle&&) = default;
private:
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<TextSprite> m_textSprite;
entt::entity m_entity;
};
@ -221,8 +221,8 @@ namespace Nz
struct StyleConfig
{
std::shared_ptr<Material> backgroundHorizontalMaterial;
std::shared_ptr<Material> backgroundVerticalMaterial;
std::shared_ptr<MaterialInstance> backgroundHorizontalMaterial;
std::shared_ptr<MaterialInstance> backgroundVerticalMaterial;
};
private:
@ -257,10 +257,10 @@ namespace Nz
struct StyleConfig
{
std::shared_ptr<Material> material;
std::shared_ptr<Material> grabbedMaterial;
std::shared_ptr<Material> grabbedHoveredMaterial;
std::shared_ptr<Material> hoveredMaterial;
std::shared_ptr<MaterialInstance> material;
std::shared_ptr<MaterialInstance> grabbedMaterial;
std::shared_ptr<MaterialInstance> grabbedHoveredMaterial;
std::shared_ptr<MaterialInstance> hoveredMaterial;
float cornerSize;
float cornerTexCoords;
};
@ -270,10 +270,10 @@ namespace Nz
private:
StyleConfig m_config;
std::shared_ptr<Material> m_hoveredMaterial;
std::shared_ptr<Material> m_material;
std::shared_ptr<Material> m_pressedMaterial;
std::shared_ptr<Material> m_pressedHoveredMaterial;
std::shared_ptr<MaterialInstance> m_hoveredMaterial;
std::shared_ptr<MaterialInstance> m_material;
std::shared_ptr<MaterialInstance> m_pressedMaterial;
std::shared_ptr<MaterialInstance> m_pressedHoveredMaterial;
std::shared_ptr<SlicedSprite> m_sprite;
entt::entity m_entity;
bool m_isHovered;

View File

@ -56,18 +56,18 @@ namespace Nz
struct Config
{
std::shared_ptr<Material> scrollbarButtonDownMaterial;
std::shared_ptr<Material> scrollbarButtonDownHoveredMaterial;
std::shared_ptr<Material> scrollbarButtonDownPressedMaterial;
std::shared_ptr<Material> scrollbarButtonLeftMaterial;
std::shared_ptr<Material> scrollbarButtonLeftHoveredMaterial;
std::shared_ptr<Material> scrollbarButtonLeftPressedMaterial;
std::shared_ptr<Material> scrollbarButtonRightMaterial;
std::shared_ptr<Material> scrollbarButtonRightHoveredMaterial;
std::shared_ptr<Material> scrollbarButtonRightPressedMaterial;
std::shared_ptr<Material> scrollbarButtonUpMaterial;
std::shared_ptr<Material> scrollbarButtonUpHoveredMaterial;
std::shared_ptr<Material> scrollbarButtonUpPressedMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonDownMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonDownHoveredMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonDownPressedMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonLeftMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonLeftHoveredMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonLeftPressedMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonRightMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonRightHoveredMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonRightPressedMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonUpMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonUpHoveredMaterial;
std::shared_ptr<MaterialInstance> scrollbarButtonUpPressedMaterial;
float scrollbarButtonCornerSize;
float scrollbarButtonCornerTexcoords;
};

Some files were not shown because too many files have changed in this diff Show More