Commit current work
Reworked conditions, added uber-shaders, comparison nodes, fixed Discard
This commit is contained in:
parent
ed72d668d9
commit
f327932738
|
|
@ -5,5 +5,6 @@ MODULE.ClientOnly = true
|
||||||
MODULE.Libraries = {
|
MODULE.Libraries = {
|
||||||
"NazaraCore",
|
"NazaraCore",
|
||||||
"NazaraRenderer",
|
"NazaraRenderer",
|
||||||
|
"NazaraShader",
|
||||||
"NazaraUtility"
|
"NazaraUtility"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,20 +35,6 @@ int main()
|
||||||
|
|
||||||
std::shared_ptr<Nz::RenderDevice> device = window.GetRenderDevice();
|
std::shared_ptr<Nz::RenderDevice> device = window.GetRenderDevice();
|
||||||
|
|
||||||
/*auto fragmentShader = device->InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, "frag.shader");
|
|
||||||
if (!fragmentShader)
|
|
||||||
{
|
|
||||||
std::cout << "Failed to instantiate fragment shader" << std::endl;
|
|
||||||
return __LINE__;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto vertexShader = device->InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraBinary, "vert.shader");
|
|
||||||
if (!vertexShader)
|
|
||||||
{
|
|
||||||
std::cout << "Failed to instantiate fragment shader" << std::endl;
|
|
||||||
return __LINE__;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/Spaceship/spaceship.obj", meshParams);
|
Nz::MeshRef drfreak = Nz::Mesh::LoadFromFile("resources/Spaceship/spaceship.obj", meshParams);
|
||||||
if (!drfreak)
|
if (!drfreak)
|
||||||
{
|
{
|
||||||
|
|
@ -89,20 +75,49 @@ int main()
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Texture (alpha-map)
|
||||||
|
Nz::ImageRef alphaImage = Nz::Image::LoadFromFile("alphatest.png");
|
||||||
|
if (!alphaImage || !alphaImage->Convert(Nz::PixelFormat_RGBA8))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to load image");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::TextureInfo alphaTexParams;
|
||||||
|
alphaTexParams.pixelFormat = alphaImage->GetFormat();
|
||||||
|
alphaTexParams.type = alphaImage->GetType();
|
||||||
|
alphaTexParams.width = alphaImage->GetWidth();
|
||||||
|
alphaTexParams.height = alphaImage->GetHeight();
|
||||||
|
alphaTexParams.depth = alphaImage->GetDepth();
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::Texture> alphaTexture = device->InstantiateTexture(alphaTexParams);
|
||||||
|
if (!alphaTexture->Update(alphaImage->GetConstPixels()))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to update texture");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
std::shared_ptr<Nz::TextureSampler> textureSampler = device->InstantiateTextureSampler({});
|
||||||
|
|
||||||
Nz::Material material(Nz::BasicMaterial::GetSettings());
|
Nz::Material material(Nz::BasicMaterial::GetSettings());
|
||||||
//material.SetShader(Nz::ShaderStageType::Fragment, fragmentShader);
|
|
||||||
//material.SetShader(Nz::ShaderStageType::Vertex, vertexShader);
|
|
||||||
material.EnableDepthBuffer(true);
|
material.EnableDepthBuffer(true);
|
||||||
material.SetTexture(0, texture);
|
|
||||||
material.SetTextureSampler(0, textureSampler);
|
Nz::BasicMaterial basicMat(material);
|
||||||
|
basicMat.EnableAlphaTest(true);
|
||||||
|
basicMat.SetAlphaMap(alphaTexture);
|
||||||
|
basicMat.SetAlphaSampler(textureSampler);
|
||||||
|
basicMat.SetDiffuseMap(alphaTexture);
|
||||||
|
basicMat.SetDiffuseSampler(textureSampler);
|
||||||
|
|
||||||
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
Nz::PredefinedInstanceData instanceUboOffsets = Nz::PredefinedInstanceData::GetOffsets();
|
||||||
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
Nz::PredefinedViewerData viewerUboOffsets = Nz::PredefinedViewerData::GetOffsets();
|
||||||
|
const Nz::BasicMaterial::UniformOffsets& materialSettingOffsets = Nz::BasicMaterial::GetOffsets();
|
||||||
|
|
||||||
std::vector<std::uint8_t> instanceDataBuffer(instanceUboOffsets.totalSize);
|
std::vector<std::uint8_t> instanceDataBuffer(instanceUboOffsets.totalSize);
|
||||||
std::vector<std::uint8_t> viewerDataBuffer(viewerUboOffsets.totalSize);
|
std::vector<std::uint8_t> viewerDataBuffer(viewerUboOffsets.totalSize);
|
||||||
|
std::vector<std::uint8_t> materialSettings(materialSettingOffsets.totalSize);
|
||||||
|
|
||||||
Nz::Vector2ui windowSize = window.GetSize();
|
Nz::Vector2ui windowSize = window.GetSize();
|
||||||
|
|
||||||
|
|
@ -110,6 +125,9 @@ int main()
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.viewMatrixOffset) = Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1);
|
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.viewMatrixOffset) = Nz::Matrix4f::Translate(Nz::Vector3f::Backward() * 1);
|
||||||
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.projMatrixOffset) = Nz::Matrix4f::Perspective(70.f, float(windowSize.x) / windowSize.y, 0.1f, 1000.f);
|
Nz::AccessByOffset<Nz::Matrix4f&>(viewerDataBuffer.data(), viewerUboOffsets.projMatrixOffset) = Nz::Matrix4f::Perspective(70.f, float(windowSize.x) / windowSize.y, 0.1f, 1000.f);
|
||||||
|
|
||||||
|
Nz::AccessByOffset<float&>(materialSettings.data(), materialSettingOffsets.alphaThreshold) = 0.5f;
|
||||||
|
Nz::AccessByOffset<Nz::Vector4f&>(materialSettings.data(), materialSettingOffsets.diffuseColor) = Nz::Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||||
|
|
||||||
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = material.GetSettings()->GetRenderPipelineLayout();
|
std::shared_ptr<Nz::RenderPipelineLayout> renderPipelineLayout = material.GetSettings()->GetRenderPipelineLayout();
|
||||||
|
|
||||||
std::shared_ptr<Nz::AbstractBuffer> instanceDataUbo = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
std::shared_ptr<Nz::AbstractBuffer> instanceDataUbo = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
||||||
|
|
@ -128,6 +146,15 @@ int main()
|
||||||
return __LINE__;
|
return __LINE__;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Nz::AbstractBuffer> matSettingUBO = device->InstantiateBuffer(Nz::BufferType_Uniform);
|
||||||
|
if (!matSettingUBO->Initialize(materialSettings.size(), Nz::BufferUsage_DeviceLocal | Nz::BufferUsage_Dynamic))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create mat setting UBO");
|
||||||
|
return __LINE__;
|
||||||
|
}
|
||||||
|
|
||||||
|
matSettingUBO->Fill(materialSettings.data(), 0, materialSettings.size());
|
||||||
|
|
||||||
Nz::ShaderBindingPtr shaderBinding = renderPipelineLayout->AllocateShaderBinding();
|
Nz::ShaderBindingPtr shaderBinding = renderPipelineLayout->AllocateShaderBinding();
|
||||||
shaderBinding->Update({
|
shaderBinding->Update({
|
||||||
{
|
{
|
||||||
|
|
@ -142,6 +169,18 @@ int main()
|
||||||
instanceDataUbo.get(), 0, instanceDataBuffer.size()
|
instanceDataUbo.get(), 0, instanceDataBuffer.size()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
3,
|
||||||
|
Nz::ShaderBinding::UniformBufferBinding {
|
||||||
|
matSettingUBO.get(), 0, materialSettings.size()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0,
|
||||||
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
alphaTexture.get(), textureSampler.get()
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
1,
|
1,
|
||||||
Nz::ShaderBinding::TextureBinding {
|
Nz::ShaderBinding::TextureBinding {
|
||||||
|
|
|
||||||
|
|
@ -17,30 +17,48 @@ namespace Nz
|
||||||
friend class MaterialPipeline;
|
friend class MaterialPipeline;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
struct UniformOffsets;
|
||||||
|
|
||||||
BasicMaterial(Material& material);
|
BasicMaterial(Material& material);
|
||||||
|
|
||||||
|
inline void EnableAlphaTest(bool alphaTest);
|
||||||
|
|
||||||
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
inline const std::shared_ptr<Texture>& GetAlphaMap() const;
|
||||||
float GetAlphaThreshold() const;
|
inline const std::shared_ptr<TextureSampler>& GetAlphaSampler() const;
|
||||||
|
float GetAlphaTestThreshold() const;
|
||||||
Color GetDiffuseColor() const;
|
Color GetDiffuseColor() const;
|
||||||
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
|
inline const std::shared_ptr<Texture>& GetDiffuseMap() const;
|
||||||
|
inline const std::shared_ptr<TextureSampler>& GetDiffuseSampler() const;
|
||||||
|
|
||||||
inline bool HasAlphaMap() const;
|
inline bool HasAlphaMap() const;
|
||||||
inline bool HasAlphaThreshold() const;
|
inline bool HasAlphaTest() const;
|
||||||
|
inline bool HasAlphaTestThreshold() const;
|
||||||
inline bool HasDiffuseColor() const;
|
inline bool HasDiffuseColor() const;
|
||||||
inline bool HasDiffuseMap() const;
|
inline bool HasDiffuseMap() const;
|
||||||
|
|
||||||
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
inline void SetAlphaMap(std::shared_ptr<Texture> alphaMap);
|
||||||
void SetAlphaThreshold(float alphaThreshold);
|
inline void SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler);
|
||||||
|
void SetAlphaTestThreshold(float alphaThreshold);
|
||||||
void SetDiffuseColor(const Color& diffuse);
|
void SetDiffuseColor(const Color& diffuse);
|
||||||
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
|
inline void SetDiffuseMap(std::shared_ptr<Texture> diffuseMap);
|
||||||
|
inline void SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler);
|
||||||
|
|
||||||
static const std::shared_ptr<MaterialSettings>& GetSettings();
|
static inline const UniformOffsets& GetOffsets();
|
||||||
|
static inline const std::shared_ptr<MaterialSettings>& GetSettings();
|
||||||
|
|
||||||
private:
|
|
||||||
struct UniformOffsets
|
struct UniformOffsets
|
||||||
{
|
{
|
||||||
std::size_t alphaThreshold;
|
std::size_t alphaThreshold;
|
||||||
std::size_t diffuseColor;
|
std::size_t diffuseColor;
|
||||||
|
std::size_t totalSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct ConditionIndexes
|
||||||
|
{
|
||||||
|
std::size_t alphaTest;
|
||||||
|
std::size_t hasAlphaMap;
|
||||||
|
std::size_t hasDiffuseMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureIndexes
|
struct TextureIndexes
|
||||||
|
|
@ -54,11 +72,13 @@ namespace Nz
|
||||||
|
|
||||||
Material& m_material;
|
Material& m_material;
|
||||||
std::size_t m_uniformBlockIndex;
|
std::size_t m_uniformBlockIndex;
|
||||||
|
ConditionIndexes m_conditionIndexes;
|
||||||
TextureIndexes m_textureIndexes;
|
TextureIndexes m_textureIndexes;
|
||||||
UniformOffsets m_uniformOffsets;
|
UniformOffsets m_uniformOffsets;
|
||||||
|
|
||||||
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
static std::shared_ptr<MaterialSettings> s_materialSettings;
|
||||||
static std::size_t s_uniformBlockIndex;
|
static std::size_t s_uniformBlockIndex;
|
||||||
|
static ConditionIndexes s_conditionIndexes;
|
||||||
static TextureIndexes s_textureIndexes;
|
static TextureIndexes s_textureIndexes;
|
||||||
static UniformOffsets s_uniformOffsets;
|
static UniformOffsets s_uniformOffsets;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,24 +9,47 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
inline void BasicMaterial::EnableAlphaTest(bool alphaTest)
|
||||||
|
{
|
||||||
|
NazaraAssert(HasAlphaTest(), "Material has no alpha test condition");
|
||||||
|
m_material.EnableCondition(m_conditionIndexes.alphaTest, alphaTest);
|
||||||
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
|
inline const std::shared_ptr<Texture>& BasicMaterial::GetAlphaMap() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
|
||||||
return m_material.GetTexture(m_textureIndexes.alpha);
|
return m_material.GetTexture(m_textureIndexes.alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetAlphaSampler() const
|
||||||
|
{
|
||||||
|
NazaraAssert(HasAlphaMap(), "Material has no alpha texture slot");
|
||||||
|
return m_material.GetTextureSampler(m_textureIndexes.alpha);
|
||||||
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<Texture>& BasicMaterial::GetDiffuseMap() const
|
inline const std::shared_ptr<Texture>& BasicMaterial::GetDiffuseMap() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseMap(), "Material has no alpha map slot");
|
NazaraAssert(HasDiffuseMap(), "Material has no alpha texture slot");
|
||||||
return m_material.GetTexture(m_textureIndexes.diffuse);
|
return m_material.GetTexture(m_textureIndexes.diffuse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const std::shared_ptr<TextureSampler>& BasicMaterial::GetDiffuseSampler() const
|
||||||
|
{
|
||||||
|
NazaraAssert(HasDiffuseMap(), "Material has no alpha texture slot");
|
||||||
|
return m_material.GetTextureSampler(m_textureIndexes.diffuse);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool BasicMaterial::HasAlphaMap() const
|
inline bool BasicMaterial::HasAlphaMap() const
|
||||||
{
|
{
|
||||||
return m_textureIndexes.alpha != MaterialSettings::InvalidIndex;
|
return m_textureIndexes.alpha != MaterialSettings::InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool BasicMaterial::HasAlphaThreshold() const
|
inline bool BasicMaterial::HasAlphaTest() const
|
||||||
|
{
|
||||||
|
return m_conditionIndexes.alphaTest != MaterialSettings::InvalidIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool BasicMaterial::HasAlphaTestThreshold() const
|
||||||
{
|
{
|
||||||
return m_uniformOffsets.alphaThreshold != MaterialSettings::InvalidIndex;
|
return m_uniformOffsets.alphaThreshold != MaterialSettings::InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
@ -44,13 +67,43 @@ namespace Nz
|
||||||
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
|
inline void BasicMaterial::SetAlphaMap(std::shared_ptr<Texture> alphaMap)
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
||||||
|
bool hasAlphaMap = (alphaMap != nullptr);
|
||||||
m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
|
m_material.SetTexture(m_textureIndexes.alpha, std::move(alphaMap));
|
||||||
|
|
||||||
|
if (m_conditionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex)
|
||||||
|
m_material.EnableCondition(m_conditionIndexes.hasAlphaMap, hasAlphaMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void BasicMaterial::SetAlphaSampler(std::shared_ptr<TextureSampler> alphaSampler)
|
||||||
|
{
|
||||||
|
NazaraAssert(HasAlphaMap(), "Material has no alpha map slot");
|
||||||
|
m_material.SetTextureSampler(m_textureIndexes.alpha, std::move(alphaSampler));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void BasicMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
|
inline void BasicMaterial::SetDiffuseMap(std::shared_ptr<Texture> diffuseMap)
|
||||||
{
|
{
|
||||||
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
||||||
|
bool hasDiffuseMap = (diffuseMap != nullptr);
|
||||||
m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
|
m_material.SetTexture(m_textureIndexes.diffuse, std::move(diffuseMap));
|
||||||
|
|
||||||
|
if (m_conditionIndexes.hasDiffuseMap != MaterialSettings::InvalidIndex)
|
||||||
|
m_material.EnableCondition(m_conditionIndexes.hasDiffuseMap, hasDiffuseMap);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void BasicMaterial::SetDiffuseSampler(std::shared_ptr<TextureSampler> diffuseSampler)
|
||||||
|
{
|
||||||
|
NazaraAssert(HasDiffuseMap(), "Material has no diffuse map slot");
|
||||||
|
m_material.SetTextureSampler(m_textureIndexes.diffuse, std::move(diffuseSampler));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const std::shared_ptr<MaterialSettings>& BasicMaterial::GetSettings()
|
||||||
|
{
|
||||||
|
return s_materialSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto BasicMaterial::GetOffsets() -> const UniformOffsets&
|
||||||
|
{
|
||||||
|
return s_uniformOffsets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ namespace Nz
|
||||||
inline void EnableAlphaTest(bool alphaTest);
|
inline void EnableAlphaTest(bool alphaTest);
|
||||||
inline void EnableBlending(bool blending);
|
inline void EnableBlending(bool blending);
|
||||||
inline void EnableColorWrite(bool colorWrite);
|
inline void EnableColorWrite(bool colorWrite);
|
||||||
|
inline void EnableCondition(std::size_t conditionIndex, bool enable);
|
||||||
inline void EnableDepthBuffer(bool depthBuffer);
|
inline void EnableDepthBuffer(bool depthBuffer);
|
||||||
inline void EnableDepthSorting(bool depthSorting);
|
inline void EnableDepthSorting(bool depthSorting);
|
||||||
inline void EnableDepthWrite(bool depthWrite);
|
inline void EnableDepthWrite(bool depthWrite);
|
||||||
|
|
@ -53,7 +54,7 @@ namespace Nz
|
||||||
inline void EnableVertexColor(bool vertexColor);
|
inline void EnableVertexColor(bool vertexColor);
|
||||||
|
|
||||||
inline void EnsurePipelineUpdate() const;
|
inline void EnsurePipelineUpdate() const;
|
||||||
|
|
||||||
inline RendererComparison GetDepthCompareFunc() const;
|
inline RendererComparison GetDepthCompareFunc() const;
|
||||||
inline BlendFunc GetDstBlend() const;
|
inline BlendFunc GetDstBlend() const;
|
||||||
inline FaceSide GetFaceCulling() const;
|
inline FaceSide GetFaceCulling() const;
|
||||||
|
|
@ -63,7 +64,7 @@ namespace Nz
|
||||||
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
inline const MaterialPipelineInfo& GetPipelineInfo() const;
|
||||||
inline float GetPointSize() const;
|
inline float GetPointSize() const;
|
||||||
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
inline const std::shared_ptr<const MaterialSettings>& GetSettings() const;
|
||||||
inline const std::shared_ptr<ShaderStage>& GetShader(ShaderStageType shaderStage) const;
|
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType shaderStage) const;
|
||||||
inline BlendFunc GetSrcBlend() const;
|
inline BlendFunc GetSrcBlend() const;
|
||||||
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
inline const std::shared_ptr<Texture>& GetTexture(std::size_t textureIndex) const;
|
||||||
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(std::size_t textureIndex) const;
|
inline const std::shared_ptr<TextureSampler>& GetTextureSampler(std::size_t textureIndex) const;
|
||||||
|
|
@ -76,6 +77,7 @@ namespace Nz
|
||||||
inline bool IsAlphaTestEnabled() const;
|
inline bool IsAlphaTestEnabled() const;
|
||||||
inline bool IsBlendingEnabled() const;
|
inline bool IsBlendingEnabled() const;
|
||||||
inline bool IsColorWriteEnabled() const;
|
inline bool IsColorWriteEnabled() const;
|
||||||
|
inline bool IsConditionEnabled(std::size_t conditionIndex) const;
|
||||||
inline bool IsDepthBufferEnabled() const;
|
inline bool IsDepthBufferEnabled() const;
|
||||||
inline bool IsDepthSortingEnabled() const;
|
inline bool IsDepthSortingEnabled() const;
|
||||||
inline bool IsDepthWriteEnabled() const;
|
inline bool IsDepthWriteEnabled() const;
|
||||||
|
|
@ -92,7 +94,6 @@ namespace Nz
|
||||||
inline void SetFaceFilling(FaceFilling filling);
|
inline void SetFaceFilling(FaceFilling filling);
|
||||||
inline void SetLineWidth(float lineWidth);
|
inline void SetLineWidth(float lineWidth);
|
||||||
inline void SetPointSize(float pointSize);
|
inline void SetPointSize(float pointSize);
|
||||||
inline void SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader);
|
|
||||||
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer);
|
inline void SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer);
|
||||||
inline void SetSrcBlend(BlendFunc func);
|
inline void SetSrcBlend(BlendFunc func);
|
||||||
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
inline void SetTexture(std::size_t textureIndex, std::shared_ptr<Texture> texture);
|
||||||
|
|
@ -115,7 +116,8 @@ namespace Nz
|
||||||
std::vector<MaterialTexture> m_textures;
|
std::vector<MaterialTexture> m_textures;
|
||||||
std::vector<UniformBufferRef> m_uniformBuffers;
|
std::vector<UniformBufferRef> m_uniformBuffers;
|
||||||
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
mutable std::shared_ptr<MaterialPipeline> m_pipeline;
|
||||||
MaterialPipelineInfo m_pipelineInfo;
|
UInt32 m_enabledConditions;
|
||||||
|
mutable MaterialPipelineInfo m_pipelineInfo;
|
||||||
mutable bool m_pipelineUpdated;
|
mutable bool m_pipelineUpdated;
|
||||||
bool m_shadowCastingEnabled;
|
bool m_shadowCastingEnabled;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -111,6 +111,15 @@ namespace Nz
|
||||||
InvalidatePipeline();
|
InvalidatePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void Material::EnableCondition(std::size_t conditionIndex, bool enable)
|
||||||
|
{
|
||||||
|
if (TestBit<UInt64>(m_enabledConditions, conditionIndex) != enable)
|
||||||
|
{
|
||||||
|
m_enabledConditions = SetBit<UInt64>(m_enabledConditions, conditionIndex);
|
||||||
|
InvalidatePipeline();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Enable/Disable depth buffer for this material
|
* \brief Enable/Disable depth buffer for this material
|
||||||
*
|
*
|
||||||
|
|
@ -428,9 +437,9 @@ namespace Nz
|
||||||
* \brief Gets the über-shader used by this material
|
* \brief Gets the über-shader used by this material
|
||||||
* \return Constant pointer to the über-shader used
|
* \return Constant pointer to the über-shader used
|
||||||
*/
|
*/
|
||||||
inline const std::shared_ptr<ShaderStage>& Material::GetShader(ShaderStageType shaderStage) const
|
inline const std::shared_ptr<UberShader>& Material::GetShader(ShaderStageType shaderStage) const
|
||||||
{
|
{
|
||||||
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)];
|
return m_pipelineInfo.shaders[UnderlyingCast(shaderStage)].uberShader;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
@ -507,6 +516,11 @@ namespace Nz
|
||||||
return m_pipelineInfo.colorWrite;
|
return m_pipelineInfo.colorWrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Material::IsConditionEnabled(std::size_t conditionIndex) const
|
||||||
|
{
|
||||||
|
return TestBit<UInt64>(m_enabledConditions, conditionIndex);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Checks whether this material has depth buffer enabled
|
* \brief Checks whether this material has depth buffer enabled
|
||||||
* \return true If it is the case
|
* \return true If it is the case
|
||||||
|
|
@ -682,22 +696,6 @@ namespace Nz
|
||||||
InvalidatePipeline();
|
InvalidatePipeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
* \brief Sets the shader with a constant reference to a ubershader
|
|
||||||
*
|
|
||||||
* \param uberShader Uber shader to apply
|
|
||||||
*
|
|
||||||
* \remark Invalidates the pipeline
|
|
||||||
*
|
|
||||||
* \see GetShader
|
|
||||||
*/
|
|
||||||
inline void Material::SetShader(ShaderStageType shaderStage, std::shared_ptr<ShaderStage> shader)
|
|
||||||
{
|
|
||||||
m_pipelineInfo.shaders[UnderlyingCast(shaderStage)] = std::move(shader);
|
|
||||||
|
|
||||||
InvalidatePipeline();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer)
|
inline void Material::SetUniformBuffer(std::size_t bufferIndex, UniformBufferRef uniformBuffer)
|
||||||
{
|
{
|
||||||
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid shared uniform buffer index");
|
NazaraAssert(bufferIndex < m_uniformBuffers.size(), "Invalid shared uniform buffer index");
|
||||||
|
|
@ -739,6 +737,19 @@ namespace Nz
|
||||||
|
|
||||||
inline void Material::UpdatePipeline() const
|
inline void Material::UpdatePipeline() const
|
||||||
{
|
{
|
||||||
|
for (auto& shader : m_pipelineInfo.shaders)
|
||||||
|
shader.enabledConditions = 0;
|
||||||
|
|
||||||
|
const auto& conditions = m_settings->GetConditions();
|
||||||
|
for (std::size_t conditionIndex = 0; conditionIndex < conditions.size(); ++conditionIndex)
|
||||||
|
{
|
||||||
|
if (TestBit<UInt64>(m_enabledConditions, conditionIndex))
|
||||||
|
{
|
||||||
|
for (std::size_t shaderStage = 0; shaderStage < ShaderStageTypeCount; ++shaderStage)
|
||||||
|
m_pipelineInfo.shaders[shaderStage].enabledConditions |= conditions[conditionIndex].enabledConditions[shaderStage];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
m_pipeline = MaterialPipeline::Get(m_pipelineInfo);
|
||||||
m_pipelineUpdated = true;
|
m_pipelineUpdated = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,24 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class ShaderStage;
|
class UberShader;
|
||||||
|
|
||||||
struct MaterialPipelineInfo : RenderStates
|
struct MaterialPipelineInfo : RenderStates
|
||||||
{
|
{
|
||||||
|
struct ShaderStage
|
||||||
|
{
|
||||||
|
std::shared_ptr<UberShader> uberShader;
|
||||||
|
Nz::UInt64 enabledConditions = 0;
|
||||||
|
};
|
||||||
|
|
||||||
bool alphaTest = false;
|
bool alphaTest = false;
|
||||||
bool depthSorting = false;
|
bool depthSorting = false;
|
||||||
bool hasVertexColor = false;
|
bool hasVertexColor = false;
|
||||||
bool reflectionMapping = false;
|
bool reflectionMapping = false;
|
||||||
bool shadowReceive = true;
|
bool shadowReceive = true;
|
||||||
|
|
||||||
|
std::array<ShaderStage, ShaderStageTypeCount> shaders;
|
||||||
std::shared_ptr<const MaterialSettings> settings;
|
std::shared_ptr<const MaterialSettings> settings;
|
||||||
std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount> shaders;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);
|
inline bool operator==(const MaterialPipelineInfo& lhs, const MaterialPipelineInfo& rhs);
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,10 @@ namespace Nz
|
||||||
|
|
||||||
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
|
for (std::size_t i = 0; i < lhs.shaders.size(); ++i)
|
||||||
{
|
{
|
||||||
if (lhs.shaders[i] != rhs.shaders[i])
|
if (lhs.shaders[i].enabledConditions != rhs.shaders[i].enabledConditions)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (lhs.shaders[i].uberShader != rhs.shaders[i].uberShader)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -82,7 +85,10 @@ namespace std
|
||||||
NazaraPipelineMember(settings.get()); //< Hash pointer
|
NazaraPipelineMember(settings.get()); //< Hash pointer
|
||||||
|
|
||||||
for (const auto& shader : pipelineInfo.shaders)
|
for (const auto& shader : pipelineInfo.shaders)
|
||||||
Nz::HashCombine(seed, shader.get());
|
{
|
||||||
|
Nz::HashCombine(seed, shader.enabledConditions);
|
||||||
|
Nz::HashCombine(seed, shader.uberShader.get());
|
||||||
|
}
|
||||||
|
|
||||||
#undef NazaraPipelineMember
|
#undef NazaraPipelineMember
|
||||||
#undef NazaraPipelineBoolMember
|
#undef NazaraPipelineBoolMember
|
||||||
|
|
|
||||||
|
|
@ -19,29 +19,35 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
class UberShader;
|
||||||
|
|
||||||
class MaterialSettings
|
class MaterialSettings
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using DefaultShaders = std::array<std::shared_ptr<ShaderStage>, ShaderStageTypeCount>;
|
|
||||||
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
|
using PredefinedBinding = std::array<std::size_t, PredefinedShaderBindingCount>;
|
||||||
|
using Shaders = std::array<std::shared_ptr<UberShader>, ShaderStageTypeCount>;
|
||||||
|
|
||||||
|
struct Builder;
|
||||||
|
struct Condition;
|
||||||
struct SharedUniformBlock;
|
struct SharedUniformBlock;
|
||||||
struct Texture;
|
struct Texture;
|
||||||
struct UniformBlock;
|
struct UniformBlock;
|
||||||
|
|
||||||
inline MaterialSettings();
|
inline MaterialSettings();
|
||||||
inline MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBinding, DefaultShaders defaultShaders);
|
inline MaterialSettings(Builder builder);
|
||||||
MaterialSettings(const MaterialSettings&) = default;
|
MaterialSettings(const MaterialSettings&) = default;
|
||||||
MaterialSettings(MaterialSettings&&) = delete;
|
MaterialSettings(MaterialSettings&&) = delete;
|
||||||
~MaterialSettings() = default;
|
~MaterialSettings() = default;
|
||||||
|
|
||||||
inline const std::shared_ptr<ShaderStage>& GetDefaultShader(ShaderStageType stage) const;
|
inline const std::vector<Condition>& GetConditions() const;
|
||||||
inline const DefaultShaders& GetDefaultShaders() const;
|
inline std::size_t GetConditionIndex(const std::string_view& name) const;
|
||||||
inline std::size_t GetPredefinedBindingIndex(PredefinedShaderBinding binding) const;
|
inline std::size_t GetPredefinedBindingIndex(PredefinedShaderBinding binding) const;
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
inline const std::shared_ptr<RenderPipelineLayout>& GetRenderPipelineLayout() const;
|
||||||
|
inline const std::shared_ptr<UberShader>& GetShader(ShaderStageType stage) const;
|
||||||
|
inline const Shaders& GetShaders() const;
|
||||||
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
|
inline const std::vector<SharedUniformBlock>& GetSharedUniformBlocks() const;
|
||||||
inline std::size_t GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const;
|
|
||||||
inline std::size_t GetSharedUniformBlockIndex(const std::string_view& name) 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 const std::vector<Texture>& GetTextures() const;
|
||||||
inline std::size_t GetTextureIndex(const std::string_view& name) const;
|
inline std::size_t GetTextureIndex(const std::string_view& name) const;
|
||||||
inline const std::vector<UniformBlock>& GetUniformBlocks() const;
|
inline const std::vector<UniformBlock>& GetUniformBlocks() const;
|
||||||
|
|
@ -53,6 +59,22 @@ namespace Nz
|
||||||
|
|
||||||
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
|
static constexpr std::size_t InvalidIndex = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
|
struct Builder
|
||||||
|
{
|
||||||
|
PredefinedBinding predefinedBinding;
|
||||||
|
Shaders shaders;
|
||||||
|
std::vector<Condition> conditions;
|
||||||
|
std::vector<Texture> textures;
|
||||||
|
std::vector<UniformBlock> uniformBlocks;
|
||||||
|
std::vector<SharedUniformBlock> sharedUniformBlocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Condition
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
std::array<UInt64, ShaderStageTypeCount> enabledConditions;
|
||||||
|
};
|
||||||
|
|
||||||
struct UniformVariable
|
struct UniformVariable
|
||||||
{
|
{
|
||||||
std::string name;
|
std::string name;
|
||||||
|
|
@ -84,11 +106,7 @@ namespace Nz
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<RenderPipelineLayout> m_pipelineLayout;
|
std::shared_ptr<RenderPipelineLayout> m_pipelineLayout;
|
||||||
std::vector<SharedUniformBlock> m_sharedUniformBlocks;
|
Builder m_data;
|
||||||
std::vector<Texture> m_textures;
|
|
||||||
std::vector<UniformBlock> m_uniformBlocks;
|
|
||||||
DefaultShaders m_defaultShaders;
|
|
||||||
PredefinedBinding m_predefinedBinding;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,22 +10,18 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline MaterialSettings::MaterialSettings() :
|
inline MaterialSettings::MaterialSettings() :
|
||||||
MaterialSettings({}, {}, {}, { InvalidIndex }, {})
|
MaterialSettings(Builder{})
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline MaterialSettings::MaterialSettings(std::vector<Texture> textures, std::vector<UniformBlock> uniformBlocks, std::vector<SharedUniformBlock> sharedUniformBlocks, const PredefinedBinding& predefinedBindings, DefaultShaders defaultShaders) :
|
inline MaterialSettings::MaterialSettings(Builder data) :
|
||||||
m_sharedUniformBlocks(std::move(sharedUniformBlocks)),
|
m_data(std::move(data))
|
||||||
m_textures(std::move(textures)),
|
|
||||||
m_uniformBlocks(std::move(uniformBlocks)),
|
|
||||||
m_defaultShaders(std::move(defaultShaders)),
|
|
||||||
m_predefinedBinding(predefinedBindings)
|
|
||||||
{
|
{
|
||||||
RenderPipelineLayoutInfo info;
|
RenderPipelineLayoutInfo info;
|
||||||
|
|
||||||
unsigned int bindingIndex = 0;
|
unsigned int bindingIndex = 0;
|
||||||
|
|
||||||
for (const Texture& textureInfo : m_textures)
|
for (const Texture& textureInfo : m_data.textures)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
//textureInfo.bindingPoint,
|
//textureInfo.bindingPoint,
|
||||||
|
|
@ -35,7 +31,7 @@ namespace Nz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const UniformBlock& ubo : m_uniformBlocks)
|
for (const UniformBlock& ubo : m_data.uniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
//ubo.bindingPoint,
|
//ubo.bindingPoint,
|
||||||
|
|
@ -45,7 +41,7 @@ namespace Nz
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const SharedUniformBlock& ubo : m_sharedUniformBlocks)
|
for (const SharedUniformBlock& ubo : m_data.sharedUniformBlocks)
|
||||||
{
|
{
|
||||||
info.bindings.push_back({
|
info.bindings.push_back({
|
||||||
//ubo.bindingPoint,
|
//ubo.bindingPoint,
|
||||||
|
|
@ -58,19 +54,25 @@ namespace Nz
|
||||||
m_pipelineLayout = Graphics::Instance()->GetRenderDevice().InstantiateRenderPipelineLayout(std::move(info));
|
m_pipelineLayout = Graphics::Instance()->GetRenderDevice().InstantiateRenderPipelineLayout(std::move(info));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<ShaderStage>& MaterialSettings::GetDefaultShader(ShaderStageType stage) const
|
inline auto MaterialSettings::GetConditions() const -> const std::vector<Condition>&
|
||||||
{
|
{
|
||||||
return m_defaultShaders[UnderlyingCast(stage)];
|
return m_data.conditions;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto MaterialSettings::GetDefaultShaders() const -> const DefaultShaders&
|
inline std::size_t MaterialSettings::GetConditionIndex(const std::string_view& name) const
|
||||||
{
|
{
|
||||||
return m_defaultShaders;
|
for (std::size_t i = 0; i < m_data.conditions.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_data.conditions[i].name == name)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetPredefinedBindingIndex(PredefinedShaderBinding binding) const
|
inline std::size_t MaterialSettings::GetPredefinedBindingIndex(PredefinedShaderBinding binding) const
|
||||||
{
|
{
|
||||||
return m_predefinedBinding[UnderlyingCast(binding)];
|
return m_data.predefinedBinding[UnderlyingCast(binding)];
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
inline const std::shared_ptr<RenderPipelineLayout>& MaterialSettings::GetRenderPipelineLayout() const
|
||||||
|
|
@ -78,32 +80,37 @@ namespace Nz
|
||||||
return m_pipelineLayout;
|
return m_pipelineLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline const std::shared_ptr<UberShader>& MaterialSettings::GetShader(ShaderStageType stage) const
|
||||||
|
{
|
||||||
|
return m_data.shaders[UnderlyingCast(stage)];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline auto MaterialSettings::GetShaders() const -> const Shaders&
|
||||||
|
{
|
||||||
|
return m_data.shaders;
|
||||||
|
}
|
||||||
|
|
||||||
inline auto MaterialSettings::GetSharedUniformBlocks() const -> const std::vector<SharedUniformBlock>&
|
inline auto MaterialSettings::GetSharedUniformBlocks() const -> const std::vector<SharedUniformBlock>&
|
||||||
{
|
{
|
||||||
return m_sharedUniformBlocks;
|
return m_data.sharedUniformBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetSharedUniformBlockIndex(const std::string_view& name) const
|
inline std::size_t MaterialSettings::GetSharedUniformBlockIndex(const std::string_view& name) const
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < m_sharedUniformBlocks.size(); ++i)
|
for (std::size_t i = 0; i < m_data.sharedUniformBlocks.size(); ++i)
|
||||||
{
|
{
|
||||||
if (m_sharedUniformBlocks[i].name == name)
|
if (m_data.sharedUniformBlocks[i].name == name)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
return InvalidIndex;
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
|
|
||||||
{
|
|
||||||
return m_textures;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
inline std::size_t MaterialSettings::GetSharedUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
||||||
{
|
{
|
||||||
assert(uniformBlockIndex < m_sharedUniformBlocks.size());
|
assert(uniformBlockIndex < m_data.sharedUniformBlocks.size());
|
||||||
|
|
||||||
const std::vector<UniformVariable>& variables = m_sharedUniformBlocks[uniformBlockIndex].uniforms;
|
const std::vector<UniformVariable>& variables = m_data.sharedUniformBlocks[uniformBlockIndex].uniforms;
|
||||||
for (std::size_t i = 0; i < variables.size(); ++i)
|
for (std::size_t i = 0; i < variables.size(); ++i)
|
||||||
{
|
{
|
||||||
if (variables[i].name == name)
|
if (variables[i].name == name)
|
||||||
|
|
@ -113,11 +120,16 @@ namespace Nz
|
||||||
return InvalidIndex;
|
return InvalidIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto MaterialSettings::GetTextures() const -> const std::vector<Texture>&
|
||||||
|
{
|
||||||
|
return m_data.textures;
|
||||||
|
}
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetTextureIndex(const std::string_view& name) const
|
inline std::size_t MaterialSettings::GetTextureIndex(const std::string_view& name) const
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < m_textures.size(); ++i)
|
for (std::size_t i = 0; i < m_data.textures.size(); ++i)
|
||||||
{
|
{
|
||||||
if (m_textures[i].name == name)
|
if (m_data.textures[i].name == name)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,14 +138,14 @@ namespace Nz
|
||||||
|
|
||||||
inline auto MaterialSettings::GetUniformBlocks() const -> const std::vector<UniformBlock>&
|
inline auto MaterialSettings::GetUniformBlocks() const -> const std::vector<UniformBlock>&
|
||||||
{
|
{
|
||||||
return m_uniformBlocks;
|
return m_data.uniformBlocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetUniformBlockIndex(const std::string_view& name) const
|
inline std::size_t MaterialSettings::GetUniformBlockIndex(const std::string_view& name) const
|
||||||
{
|
{
|
||||||
for (std::size_t i = 0; i < m_uniformBlocks.size(); ++i)
|
for (std::size_t i = 0; i < m_data.uniformBlocks.size(); ++i)
|
||||||
{
|
{
|
||||||
if (m_uniformBlocks[i].name == name)
|
if (m_data.uniformBlocks[i].name == name)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -142,9 +154,9 @@ namespace Nz
|
||||||
|
|
||||||
inline std::size_t MaterialSettings::GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
inline std::size_t MaterialSettings::GetUniformBlockVariableOffset(std::size_t uniformBlockIndex, const std::string_view& name) const
|
||||||
{
|
{
|
||||||
assert(uniformBlockIndex < m_uniformBlocks.size());
|
assert(uniformBlockIndex < m_data.uniformBlocks.size());
|
||||||
|
|
||||||
const std::vector<UniformVariable>& variables = m_uniformBlocks[uniformBlockIndex].uniforms;
|
const std::vector<UniformVariable>& variables = m_data.uniformBlocks[uniformBlockIndex].uniforms;
|
||||||
for (std::size_t i = 0; i < variables.size(); ++i)
|
for (std::size_t i = 0; i < variables.size(); ++i)
|
||||||
{
|
{
|
||||||
if (variables[i].name == name)
|
if (variables[i].name == name)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright (C) 2017 Jérôme Leclercq
|
||||||
|
// 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_UBER_SHADER_HPP
|
||||||
|
#define NAZARA_UBER_SHADER_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequisites.hpp>
|
||||||
|
#include <Nazara/Core/Bitset.hpp>
|
||||||
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderAst.hpp>
|
||||||
|
#include <unordered_map>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
class ShaderStage;
|
||||||
|
|
||||||
|
class NAZARA_GRAPHICS_API UberShader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
inline UberShader(ShaderAst shaderAst);
|
||||||
|
~UberShader() = default;
|
||||||
|
|
||||||
|
UInt64 GetConditionFlagByName(const std::string_view& condition) const;
|
||||||
|
|
||||||
|
const std::shared_ptr<ShaderStage>& Get(UInt64 combination);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unordered_map<UInt64 /*combination*/, std::shared_ptr<ShaderStage>> m_combinations;
|
||||||
|
ShaderAst m_shaderAst;
|
||||||
|
UInt64 m_combinationMask;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/UberShader.inl>
|
||||||
|
|
||||||
|
#endif // NAZARA_UBER_SHADER_HPP
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (C) 2017 Jérôme Leclercq
|
||||||
|
// 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/UberShader.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <Nazara/Graphics/DebugOff.hpp>
|
||||||
|
|
@ -36,6 +36,7 @@ namespace Nz
|
||||||
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
|
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
|
||||||
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
|
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
|
||||||
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
||||||
|
std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) override;
|
||||||
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
|
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
|
||||||
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
||||||
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,11 @@ namespace Nz
|
||||||
void Release(ShaderBinding& binding);
|
void Release(ShaderBinding& binding);
|
||||||
inline void TryToShrink();
|
inline void TryToShrink();
|
||||||
|
|
||||||
|
static constexpr UInt32 InvalidIndex = 0xFFFFFFFF;
|
||||||
|
|
||||||
struct TextureDescriptor
|
struct TextureDescriptor
|
||||||
{
|
{
|
||||||
UInt32 bindingIndex;
|
UInt32 bindingIndex = InvalidIndex;
|
||||||
GLuint texture;
|
GLuint texture;
|
||||||
GLuint sampler;
|
GLuint sampler;
|
||||||
GL::TextureTarget textureTarget;
|
GL::TextureTarget textureTarget;
|
||||||
|
|
@ -62,7 +64,7 @@ namespace Nz
|
||||||
|
|
||||||
struct UniformBufferDescriptor
|
struct UniformBufferDescriptor
|
||||||
{
|
{
|
||||||
UInt32 bindingIndex;
|
UInt32 bindingIndex = InvalidIndex;
|
||||||
GLuint buffer;
|
GLuint buffer;
|
||||||
GLintptr offset;
|
GLintptr offset;
|
||||||
GLsizeiptr size;
|
GLsizeiptr size;
|
||||||
|
|
|
||||||
|
|
@ -12,13 +12,17 @@
|
||||||
#include <Nazara/Renderer/ShaderStage.hpp>
|
#include <Nazara/Renderer/ShaderStage.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/Context.hpp>
|
||||||
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
|
#include <Nazara/OpenGLRenderer/Wrapper/Shader.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderWriter.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
class ShaderAst;
|
||||||
|
|
||||||
class NAZARA_OPENGLRENDERER_API OpenGLShaderStage : public ShaderStage
|
class NAZARA_OPENGLRENDERER_API OpenGLShaderStage : public ShaderStage
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
OpenGLShaderStage(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states);
|
||||||
OpenGLShaderStage(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
|
OpenGLShaderStage(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
|
||||||
OpenGLShaderStage(const OpenGLShaderStage&) = delete;
|
OpenGLShaderStage(const OpenGLShaderStage&) = delete;
|
||||||
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
|
OpenGLShaderStage(OpenGLShaderStage&&) noexcept = default;
|
||||||
|
|
@ -30,6 +34,9 @@ namespace Nz
|
||||||
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
|
OpenGLShaderStage& operator=(OpenGLShaderStage&&) noexcept = default;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CheckCompilationStatus();
|
||||||
|
void Create(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states);
|
||||||
|
|
||||||
GL::Shader m_shader;
|
GL::Shader m_shader;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,8 @@ namespace Nz::GL
|
||||||
{
|
{
|
||||||
inline GL::WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) :
|
inline GL::WGLContext::WGLContext(const OpenGLDevice* device, const WGLLoader& loader) :
|
||||||
Context(device),
|
Context(device),
|
||||||
m_loader(loader)
|
m_loader(loader),
|
||||||
|
m_handle(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
#include <Nazara/Renderer/RenderPipelineLayout.hpp>
|
||||||
#include <Nazara/Renderer/Texture.hpp>
|
#include <Nazara/Renderer/Texture.hpp>
|
||||||
#include <Nazara/Renderer/TextureSampler.hpp>
|
#include <Nazara/Renderer/TextureSampler.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderWriter.hpp>
|
||||||
#include <Nazara/Utility/AbstractBuffer.hpp>
|
#include <Nazara/Utility/AbstractBuffer.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
class CommandPool;
|
class CommandPool;
|
||||||
|
class ShaderAst;
|
||||||
class ShaderStage;
|
class ShaderStage;
|
||||||
|
|
||||||
class NAZARA_RENDERER_API RenderDevice
|
class NAZARA_RENDERER_API RenderDevice
|
||||||
|
|
@ -33,6 +35,7 @@ namespace Nz
|
||||||
virtual std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) = 0;
|
virtual std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) = 0;
|
||||||
virtual std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
|
virtual std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) = 0;
|
||||||
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
|
virtual std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) = 0;
|
||||||
|
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) = 0;
|
||||||
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
|
virtual std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) = 0;
|
||||||
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
|
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const std::filesystem::path& sourcePath);
|
||||||
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;
|
virtual std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) = 0;
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,8 @@ namespace Nz
|
||||||
void AddStruct(std::string name, std::vector<StructMember> members);
|
void AddStruct(std::string name, std::vector<StructMember> members);
|
||||||
void AddUniform(std::string name, ShaderExpressionType type, std::optional<std::size_t> bindingIndex = {}, std::optional<ShaderNodes::MemoryLayout> memoryLayout = {});
|
void AddUniform(std::string name, ShaderExpressionType type, std::optional<std::size_t> bindingIndex = {}, std::optional<ShaderNodes::MemoryLayout> memoryLayout = {});
|
||||||
|
|
||||||
|
inline std::size_t FindConditionByName(const std::string_view& conditionName) const;
|
||||||
|
|
||||||
inline const Condition& GetCondition(std::size_t i) const;
|
inline const Condition& GetCondition(std::size_t i) const;
|
||||||
inline std::size_t GetConditionCount() const;
|
inline std::size_t GetConditionCount() const;
|
||||||
inline const std::vector<Condition>& GetConditions() const;
|
inline const std::vector<Condition>& GetConditions() const;
|
||||||
|
|
@ -110,6 +112,8 @@ namespace Nz
|
||||||
ShaderExpressionType type;
|
ShaderExpressionType type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static constexpr std::size_t InvalidCondition = std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<Condition> m_conditions;
|
std::vector<Condition> m_conditions;
|
||||||
std::vector<Function> m_functions;
|
std::vector<Function> m_functions;
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,17 @@ namespace Nz
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::size_t ShaderAst::FindConditionByName(const std::string_view& conditionName) const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < m_conditions.size(); ++i)
|
||||||
|
{
|
||||||
|
if (m_conditions[i].name == conditionName)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InvalidCondition;
|
||||||
|
}
|
||||||
|
|
||||||
inline auto Nz::ShaderAst::GetCondition(std::size_t i) const -> const Condition&
|
inline auto Nz::ShaderAst::GetCondition(std::size_t i) const -> const Condition&
|
||||||
{
|
{
|
||||||
assert(i < m_functions.size());
|
assert(i < m_functions.size());
|
||||||
|
|
|
||||||
|
|
@ -141,6 +141,7 @@ namespace Nz
|
||||||
};
|
};
|
||||||
|
|
||||||
NAZARA_SHADER_API ByteArray SerializeShader(const ShaderAst& shader);
|
NAZARA_SHADER_API ByteArray SerializeShader(const ShaderAst& shader);
|
||||||
|
inline ShaderAst UnserializeShader(const void* data, std::size_t size);
|
||||||
NAZARA_SHADER_API ShaderAst UnserializeShader(ByteStream& stream);
|
NAZARA_SHADER_API ShaderAst UnserializeShader(ByteStream& stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -128,6 +128,12 @@ namespace Nz
|
||||||
m_stream(stream)
|
m_stream(stream)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ShaderAst UnserializeShader(const void* data, std::size_t size)
|
||||||
|
{
|
||||||
|
ByteStream byteStream(data, size);
|
||||||
|
return UnserializeShader(byteStream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <Nazara/Shader/DebugOff.hpp>
|
#include <Nazara/Shader/DebugOff.hpp>
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,12 @@ namespace Nz::ShaderBuilder
|
||||||
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
|
constexpr GenBuilder<ShaderNodes::DeclareVariable> DeclareVariable;
|
||||||
constexpr GenBuilder<ShaderNodes::Discard> Discard;
|
constexpr GenBuilder<ShaderNodes::Discard> Discard;
|
||||||
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::Divide> Divide;
|
||||||
constexpr BinOpBuilder<ShaderNodes::BinaryType::Equality> Equal;
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompEq> Equal;
|
||||||
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGt> GreaterThan;
|
||||||
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompGe> GreaterThanOrEqual;
|
||||||
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLt> LessThan;
|
||||||
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompLe> LessThanOrEqual;
|
||||||
|
constexpr BinOpBuilder<ShaderNodes::BinaryType::CompNe> NotEqual;
|
||||||
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
|
constexpr GenBuilder<ShaderNodes::ExpressionStatement> ExprStatement;
|
||||||
constexpr GenBuilder<ShaderNodes::Identifier> Identifier;
|
constexpr GenBuilder<ShaderNodes::Identifier> Identifier;
|
||||||
constexpr GenBuilder<ShaderNodes::IntrinsicCall> IntrinsicCall;
|
constexpr GenBuilder<ShaderNodes::IntrinsicCall> IntrinsicCall;
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ namespace Nz::ShaderNodes
|
||||||
UInt1, //< uint
|
UInt1, //< uint
|
||||||
UInt2, //< uvec2
|
UInt2, //< uvec2
|
||||||
UInt3, //< uvec3
|
UInt3, //< uvec3
|
||||||
UInt4 //< uvec4
|
UInt4 //< uvec4
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BinaryType
|
enum class BinaryType
|
||||||
|
|
@ -43,7 +43,12 @@ namespace Nz::ShaderNodes
|
||||||
Multiply, //< *
|
Multiply, //< *
|
||||||
Divide, //< /
|
Divide, //< /
|
||||||
|
|
||||||
Equality //< ==
|
CompEq, //< ==
|
||||||
|
CompGe, //< >=
|
||||||
|
CompGt, //< >
|
||||||
|
CompLe, //< <=
|
||||||
|
CompLt, //< <
|
||||||
|
CompNe //< <=
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class BuiltinEntry
|
enum class BuiltinEntry
|
||||||
|
|
@ -87,7 +92,9 @@ namespace Nz::ShaderNodes
|
||||||
IntrinsicCall,
|
IntrinsicCall,
|
||||||
Sample2D,
|
Sample2D,
|
||||||
SwizzleOp,
|
SwizzleOp,
|
||||||
StatementBlock
|
StatementBlock,
|
||||||
|
|
||||||
|
Max = StatementBlock
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class SsaInstruction
|
enum class SsaInstruction
|
||||||
|
|
|
||||||
|
|
@ -149,7 +149,7 @@ namespace Nz::ShaderNodes
|
||||||
|
|
||||||
|
|
||||||
inline Discard::Discard() :
|
inline Discard::Discard() :
|
||||||
Statement(NodeType::DeclareVariable)
|
Statement(NodeType::Discard)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Nz
|
||||||
|
|
||||||
struct States
|
struct States
|
||||||
{
|
{
|
||||||
std::unordered_set<std::string> enabledConditions;
|
Nz::UInt64 enabledConditions = 0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,17 @@
|
||||||
// For conditions of distribution and use, see copyright notice in Config.hpp
|
// For conditions of distribution and use, see copyright notice in Config.hpp
|
||||||
|
|
||||||
#include <Nazara/Shader/SpirvWriter.hpp>
|
#include <Nazara/Shader/SpirvWriter.hpp>
|
||||||
|
#include <Nazara/Math/Algorithm.hpp>
|
||||||
#include <Nazara/Shader/Debug.hpp>
|
#include <Nazara/Shader/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
inline bool SpirvWriter::IsConditionEnabled(const std::string& condition) const
|
inline bool SpirvWriter::IsConditionEnabled(const std::string& condition) const
|
||||||
{
|
{
|
||||||
return m_context.states->enabledConditions.find(condition) != m_context.states->enabledConditions.end();
|
std::size_t conditionIndex = m_context.shader->FindConditionByName(condition);
|
||||||
|
assert(conditionIndex != ShaderAst::InvalidCondition);
|
||||||
|
|
||||||
|
return TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ namespace Nz
|
||||||
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
|
std::shared_ptr<CommandPool> InstantiateCommandPool(QueueType queueType) override;
|
||||||
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
|
std::shared_ptr<RenderPipeline> InstantiateRenderPipeline(RenderPipelineInfo pipelineInfo) override;
|
||||||
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
std::shared_ptr<RenderPipelineLayout> InstantiateRenderPipelineLayout(RenderPipelineLayoutInfo pipelineLayoutInfo) override;
|
||||||
|
std::shared_ptr<ShaderStage> InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states) override;
|
||||||
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
|
std::shared_ptr<ShaderStage> InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize) override;
|
||||||
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
std::shared_ptr<Texture> InstantiateTexture(const TextureInfo& params) override;
|
||||||
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
std::shared_ptr<TextureSampler> InstantiateTextureSampler(const TextureSamplerInfo& params) override;
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
#include <Nazara/Prerequisites.hpp>
|
#include <Nazara/Prerequisites.hpp>
|
||||||
#include <Nazara/Renderer/Enums.hpp>
|
#include <Nazara/Renderer/Enums.hpp>
|
||||||
#include <Nazara/Renderer/ShaderStage.hpp>
|
#include <Nazara/Renderer/ShaderStage.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderWriter.hpp>
|
||||||
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
|
#include <Nazara/VulkanRenderer/Wrapper/ShaderModule.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -23,6 +24,7 @@ namespace Nz
|
||||||
VulkanShaderStage(VulkanShaderStage&&) = delete;
|
VulkanShaderStage(VulkanShaderStage&&) = delete;
|
||||||
~VulkanShaderStage() = default;
|
~VulkanShaderStage() = default;
|
||||||
|
|
||||||
|
bool Create(Vk::Device& device, const ShaderAst& shader, const ShaderWriter::States& states);
|
||||||
bool Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
|
bool Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize);
|
||||||
|
|
||||||
inline const Vk::ShaderModule& GetHandle() const;
|
inline const Vk::ShaderModule& GetHandle() const;
|
||||||
|
|
|
||||||
|
|
@ -19,35 +19,52 @@
|
||||||
"type": "UniformBufferObject"
|
"type": "UniformBufferObject"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"conditions": [
|
||||||
|
{
|
||||||
|
"name": "HAS_DIFFUSE_TEXTURE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "HAS_ALPHA_TEXTURE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ALPHA_TEST"
|
||||||
|
}
|
||||||
|
],
|
||||||
"connections": [
|
"connections": [
|
||||||
{
|
{
|
||||||
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
"in_id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
|
"in_index": 3,
|
||||||
|
"out_id": "{93fdbb4c-bc81-4100-89a9-b465793099b9}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
"in_index": 0,
|
"in_index": 0,
|
||||||
"out_id": "{ac98a68f-0160-4189-af31-b8278e7c119c}",
|
"out_id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
"in_id": "{92d95fe0-84f6-4d27-91ea-992d5f73c04e}",
|
||||||
"in_index": 1,
|
|
||||||
"out_id": "{db10f064-504d-4072-a49e-51a061b2efbe}",
|
|
||||||
"out_index": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
|
||||||
"in_index": 0,
|
"in_index": 0,
|
||||||
"out_id": "{c41cd67b-2f34-4ec4-acc6-2f7285e7c6e3}",
|
"out_id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
"in_id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
||||||
"in_index": 1,
|
"in_index": 1,
|
||||||
"out_id": "{74d3ca95-ae1d-496d-88c1-ce6c7327012a}",
|
"out_id": "{07a43c79-67e2-46b1-87d4-e00d2da22820}",
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
"in_id": "{93fdbb4c-bc81-4100-89a9-b465793099b9}",
|
||||||
"in_index": 1,
|
"in_index": 0,
|
||||||
"out_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
"out_id": "{6fcfbcd0-c2df-41dd-bb50-74b455b9021f}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -57,22 +74,136 @@
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in_id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
"in_id": "{92d95fe0-84f6-4d27-91ea-992d5f73c04e}",
|
||||||
"in_index": 1,
|
"in_index": 1,
|
||||||
"out_id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
"out_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
"out_index": 0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"in_id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
|
||||||
"in_index": 0,
|
|
||||||
"out_id": "{07a43c79-67e2-46b1-87d4-e00d2da22820}",
|
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"in_id": "{be3547ff-0bf3-4701-9c27-c21e9d1322c3}",
|
"in_id": "{be3547ff-0bf3-4701-9c27-c21e9d1322c3}",
|
||||||
"in_index": 0,
|
"in_index": 0,
|
||||||
"out_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
"out_id": "{92d95fe0-84f6-4d27-91ea-992d5f73c04e}",
|
||||||
"out_index": 0
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{e1f86d56-eb21-4267-9075-e6b0cc875a6d}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{93fdbb4c-bc81-4100-89a9-b465793099b9}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
|
"out_index": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
|
"in_index": 2,
|
||||||
|
"out_id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
|
"out_index": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{ac98a68f-0160-4189-af31-b8278e7c119c}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{7750a050-b116-4e1b-bd89-b194c366d256}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{ca2c2ac5-39e0-4814-9432-fbf3e20d3cad}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{3cdb5bb1-f572-4055-a1af-460b152b0c13}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{d7acd173-9188-43b5-bfa1-31f17dff44ad}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{c41cd67b-2f34-4ec4-acc6-2f7285e7c6e3}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{e1f86d56-eb21-4267-9075-e6b0cc875a6d}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{07a43c79-67e2-46b1-87d4-e00d2da22820}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
|
"out_index": 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{db10f064-504d-4072-a49e-51a061b2efbe}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{d7acd173-9188-43b5-bfa1-31f17dff44ad}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{1f9d52d7-4f44-4d96-8edb-fbc1239a93bb}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{bed466d8-5ed0-4e8a-bba7-1c809cb4c3f7}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{fbaddbbe-f9cd-4e8d-b7a8-40c10c96f580}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{f5a6874b-0559-4fd1-9836-27567f9696a4}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{e1f86d56-eb21-4267-9075-e6b0cc875a6d}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{cf0ae20a-88cd-4788-9ed7-eaf014d8f971}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{74d3ca95-ae1d-496d-88c1-ce6c7327012a}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{bb071807-e65e-4c31-acf0-d296efa665fa}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{92d95fe0-84f6-4d27-91ea-992d5f73c04e}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{7750a050-b116-4e1b-bd89-b194c366d256}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{f9ba0cce-3b85-4f95-a79e-a2f64d955d89}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{6fcfbcd0-c2df-41dd-bb50-74b455b9021f}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{7750a050-b116-4e1b-bd89-b194c366d256}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{d7acd173-9188-43b5-bfa1-31f17dff44ad}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{fc7542b2-5752-4891-98c1-35b498da257b}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{fc7542b2-5752-4891-98c1-35b498da257b}",
|
||||||
|
"in_index": 1,
|
||||||
|
"out_id": "{743930bd-1d81-4d4c-b7ec-175a34838d69}",
|
||||||
|
"out_index": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in_id": "{fc7542b2-5752-4891-98c1-35b498da257b}",
|
||||||
|
"in_index": 0,
|
||||||
|
"out_id": "{bb071807-e65e-4c31-acf0-d296efa665fa}",
|
||||||
|
"out_index": 3
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"inputs": [
|
"inputs": [
|
||||||
|
|
@ -103,8 +234,22 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 103,
|
"x": 330.0833333333333,
|
||||||
"y": 173
|
"y": 236.19444444444446
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{becdd0d4-2b28-44f5-86c2-2ed6b846326c}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_decompose",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1022.5200000000003,
|
||||||
|
"y": -53.35999999999996
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -117,8 +262,8 @@
|
||||||
"variable_name": "lightFactor"
|
"variable_name": "lightFactor"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 278,
|
"x": 486.33333333333326,
|
||||||
"y": 212
|
"y": 285.61111111111114
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -136,8 +281,8 @@
|
||||||
"variable_name": "lightDir"
|
"variable_name": "lightDir"
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 115,
|
"x": 294.1666666666667,
|
||||||
"y": 267
|
"y": 358.6666666666667
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -150,8 +295,8 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 299,
|
"x": 167.75,
|
||||||
"y": 488
|
"y": 473.97222222222194
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -165,8 +310,8 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 103,
|
"x": -10.194444444444457,
|
||||||
"y": 470
|
"y": 445
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -180,8 +325,8 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 113,
|
"x": -0.19444444444445708,
|
||||||
"y": 579
|
"y": 554.0000000000001
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -191,11 +336,25 @@
|
||||||
"preview_enabled": false,
|
"preview_enabled": false,
|
||||||
"preview_height": 64,
|
"preview_height": 64,
|
||||||
"preview_width": 64,
|
"preview_width": 64,
|
||||||
|
"variable_name": "textureColor"
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1055.9166666666665,
|
||||||
|
"y": 458.6388888888888
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{93fdbb4c-bc81-4100-89a9-b465793099b9}",
|
||||||
|
"model": {
|
||||||
|
"name": "float_mul",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 488,
|
"x": 1051.286666666667,
|
||||||
"y": 376
|
"y": 195.20666666666665
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -209,8 +368,8 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 912,
|
"x": 2598.5,
|
||||||
"y": 489
|
"y": 293.33333333333326
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -223,28 +382,8 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 707,
|
"x": 377.1388888888888,
|
||||||
"y": 492
|
"y": 507.83333333333337
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "{43df5c43-d6f4-440f-a049-4fde6e738883}",
|
|
||||||
"model": {
|
|
||||||
"name": "cast_vec4",
|
|
||||||
"preview_enabled": false,
|
|
||||||
"preview_height": 64,
|
|
||||||
"preview_width": 64,
|
|
||||||
"value": [
|
|
||||||
1,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"variable_name": "matDiffuse"
|
|
||||||
},
|
|
||||||
"position": {
|
|
||||||
"x": 521,
|
|
||||||
"y": 616
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -259,8 +398,198 @@
|
||||||
"variable_name": ""
|
"variable_name": ""
|
||||||
},
|
},
|
||||||
"position": {
|
"position": {
|
||||||
"x": 309,
|
"x": 135.11111111111126,
|
||||||
"y": 637
|
"y": 643.5277777777775
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{e1f86d56-eb21-4267-9075-e6b0cc875a6d}",
|
||||||
|
"model": {
|
||||||
|
"condition_name": "HAS_DIFFUSE_TEXTURE",
|
||||||
|
"name": "ConditionalExpression",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 602.5,
|
||||||
|
"y": 566.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{ca2c2ac5-39e0-4814-9432-fbf3e20d3cad}",
|
||||||
|
"model": {
|
||||||
|
"input": "vertUV",
|
||||||
|
"name": "Input",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 344.36666666666684,
|
||||||
|
"y": 53.300000000000026
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{f9ba0cce-3b85-4f95-a79e-a2f64d955d89}",
|
||||||
|
"model": {
|
||||||
|
"name": "Texture",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"texture": "MaterialAlphaMap",
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 344.59999999999985,
|
||||||
|
"y": -35.10000000000005
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{7750a050-b116-4e1b-bd89-b194c366d256}",
|
||||||
|
"model": {
|
||||||
|
"name": "SampleTexture",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 491.0333333333334,
|
||||||
|
"y": 18.366666666666674
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{6fcfbcd0-c2df-41dd-bb50-74b455b9021f}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_decompose",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 682.0999999999998,
|
||||||
|
"y": 19.88000000000003
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{359a78e1-df0d-467f-907e-7bff04a55db5}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_compose4",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1240.62,
|
||||||
|
"y": -41.900000000000034
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{bb071807-e65e-4c31-acf0-d296efa665fa}",
|
||||||
|
"model": {
|
||||||
|
"name": "vec_decompose",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 2270,
|
||||||
|
"y": 67
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{92d95fe0-84f6-4d27-91ea-992d5f73c04e}",
|
||||||
|
"model": {
|
||||||
|
"condition_name": "HAS_ALPHA_TEXTURE",
|
||||||
|
"name": "ConditionalExpression",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1415.8933333333334,
|
||||||
|
"y": 135.44000000000005
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{3cdb5bb1-f572-4055-a1af-460b152b0c13}",
|
||||||
|
"model": {
|
||||||
|
"name": "Discard",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 2694,
|
||||||
|
"y": 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{d7acd173-9188-43b5-bfa1-31f17dff44ad}",
|
||||||
|
"model": {
|
||||||
|
"condition_name": "ALPHA_TEST",
|
||||||
|
"name": "ConditionalExpression",
|
||||||
|
"preview_enabled": true,
|
||||||
|
"preview_height": 128,
|
||||||
|
"preview_width": 128,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 2240,
|
||||||
|
"y": -174
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{1f9d52d7-4f44-4d96-8edb-fbc1239a93bb}",
|
||||||
|
"model": {
|
||||||
|
"name": "bool_constant",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"value": false,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 2005,
|
||||||
|
"y": -99
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{fc7542b2-5752-4891-98c1-35b498da257b}",
|
||||||
|
"model": {
|
||||||
|
"name": "float_lt",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 2000,
|
||||||
|
"y": -241
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "{743930bd-1d81-4d4c-b7ec-175a34838d69}",
|
||||||
|
"model": {
|
||||||
|
"buffer": "settings",
|
||||||
|
"field": "AlphaThreshold",
|
||||||
|
"name": "BufferField",
|
||||||
|
"preview_enabled": false,
|
||||||
|
"preview_height": 64,
|
||||||
|
"preview_width": 64,
|
||||||
|
"variable_name": ""
|
||||||
|
},
|
||||||
|
"position": {
|
||||||
|
"x": 1675,
|
||||||
|
"y": -254
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
@ -280,7 +609,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "DiffuseColor",
|
"name": "DiffuseColor",
|
||||||
"type": "Float3"
|
"type": "Float4"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"name": "BasicSettings"
|
"name": "BasicSettings"
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ namespace Nz
|
||||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||||
wchar_t* buffer = nullptr;
|
wchar_t* buffer = nullptr;
|
||||||
|
|
||||||
FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
|
DWORD length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
nullptr,
|
nullptr,
|
||||||
code,
|
code,
|
||||||
0,
|
0,
|
||||||
|
|
@ -96,6 +96,9 @@ namespace Nz
|
||||||
0,
|
0,
|
||||||
nullptr);
|
nullptr);
|
||||||
|
|
||||||
|
if (length == 0)
|
||||||
|
return "<internal error: FormatMessageW failed with " + std::to_string(::GetLastError()) + ">";
|
||||||
|
|
||||||
CallOnExit freeOnExit([buffer] { LocalFree(buffer); });
|
CallOnExit freeOnExit([buffer] { LocalFree(buffer); });
|
||||||
return FromWideString(buffer);
|
return FromWideString(buffer);
|
||||||
#elif defined(NAZARA_PLATFORM_POSIX)
|
#elif defined(NAZARA_PLATFORM_POSIX)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,9 @@
|
||||||
#include <Nazara/Core/Algorithm.hpp>
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Core/ErrorFlags.hpp>
|
#include <Nazara/Core/ErrorFlags.hpp>
|
||||||
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
|
||||||
|
#include <Nazara/Graphics/UberShader.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderAstSerializer.hpp>
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
#include <Nazara/Utility/BufferMapper.hpp>
|
||||||
#include <Nazara/Utility/FieldOffsets.hpp>
|
#include <Nazara/Utility/FieldOffsets.hpp>
|
||||||
#include <Nazara/Utility/MaterialData.hpp>
|
#include <Nazara/Utility/MaterialData.hpp>
|
||||||
|
|
@ -33,12 +35,17 @@ namespace Nz
|
||||||
const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
|
const std::shared_ptr<const MaterialSettings>& materialSettings = material.GetSettings();
|
||||||
if (materialSettings == s_materialSettings)
|
if (materialSettings == s_materialSettings)
|
||||||
{
|
{
|
||||||
|
m_conditionIndexes = s_conditionIndexes;
|
||||||
m_textureIndexes = s_textureIndexes;
|
m_textureIndexes = s_textureIndexes;
|
||||||
m_uniformBlockIndex = s_uniformBlockIndex;
|
m_uniformBlockIndex = s_uniformBlockIndex;
|
||||||
m_uniformOffsets = s_uniformOffsets;
|
m_uniformOffsets = s_uniformOffsets;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_conditionIndexes.alphaTest = materialSettings->GetConditionIndex("AlphaTest");
|
||||||
|
m_conditionIndexes.hasAlphaMap = materialSettings->GetConditionIndex("HasAlphaMap");
|
||||||
|
m_conditionIndexes.hasDiffuseMap = materialSettings->GetConditionIndex("HasDiffuseMap");
|
||||||
|
|
||||||
m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
m_textureIndexes.alpha = materialSettings->GetTextureIndex("Alpha");
|
||||||
m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
m_textureIndexes.diffuse = materialSettings->GetTextureIndex("Diffuse");
|
||||||
|
|
||||||
|
|
@ -49,9 +56,9 @@ namespace Nz
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float BasicMaterial::GetAlphaThreshold() const
|
float BasicMaterial::GetAlphaTestThreshold() const
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_ReadOnly);
|
||||||
return AccessByOffset<const float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
|
return AccessByOffset<const float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold);
|
||||||
|
|
@ -67,9 +74,9 @@ namespace Nz
|
||||||
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
return Color(colorPtr[0] * 255, colorPtr[1] * 255, colorPtr[2] * 255, colorPtr[3] * 255); //< TODO: Make color able to use float
|
||||||
}
|
}
|
||||||
|
|
||||||
void BasicMaterial::SetAlphaThreshold(float alphaThreshold)
|
void BasicMaterial::SetAlphaTestThreshold(float alphaThreshold)
|
||||||
{
|
{
|
||||||
NazaraAssert(HasAlphaThreshold(), "Material has no alpha threshold uniform");
|
NazaraAssert(HasAlphaTestThreshold(), "Material has no alpha threshold uniform");
|
||||||
|
|
||||||
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
BufferMapper<UniformBuffer> mapper(m_material.GetUniformBuffer(m_uniformBlockIndex), BufferAccess_WriteOnly);
|
||||||
AccessByOffset<float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
|
AccessByOffset<float&>(mapper.GetPointer(), m_uniformOffsets.alphaThreshold) = alphaThreshold;
|
||||||
|
|
@ -87,20 +94,16 @@ namespace Nz
|
||||||
colorPtr[3] = diffuse.a / 255.f;
|
colorPtr[3] = diffuse.a / 255.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::shared_ptr<MaterialSettings>& BasicMaterial::GetSettings()
|
|
||||||
{
|
|
||||||
return s_materialSettings;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool BasicMaterial::Initialize()
|
bool BasicMaterial::Initialize()
|
||||||
{
|
{
|
||||||
FieldOffsets fieldOffsets(StructLayout_Std140);
|
FieldOffsets fieldOffsets(StructLayout_Std140);
|
||||||
|
|
||||||
s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
|
|
||||||
s_uniformOffsets.alphaThreshold = fieldOffsets.AddField(StructFieldType_Float1);
|
s_uniformOffsets.alphaThreshold = fieldOffsets.AddField(StructFieldType_Float1);
|
||||||
|
s_uniformOffsets.diffuseColor = fieldOffsets.AddField(StructFieldType_Float4);
|
||||||
|
s_uniformOffsets.totalSize = fieldOffsets.GetSize();
|
||||||
|
|
||||||
MaterialSettings::PredefinedBinding predefinedBinding;
|
MaterialSettings::Builder settings;
|
||||||
predefinedBinding.fill(MaterialSettings::InvalidIndex);
|
settings.predefinedBinding.fill(MaterialSettings::InvalidIndex);
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> variables;
|
std::vector<MaterialSettings::UniformVariable> variables;
|
||||||
variables.assign({
|
variables.assign({
|
||||||
|
|
@ -120,31 +123,29 @@ namespace Nz
|
||||||
AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
AccessByOffset<Vector4f&>(defaultValues.data(), s_uniformOffsets.diffuseColor) = Vector4f(1.f, 1.f, 1.f, 1.f);
|
||||||
AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
|
AccessByOffset<float&>(defaultValues.data(), s_uniformOffsets.alphaThreshold) = 0.2f;
|
||||||
|
|
||||||
std::vector<MaterialSettings::Texture> textures;
|
s_textureIndexes.alpha = settings.textures.size();
|
||||||
s_textureIndexes.alpha = textures.size();
|
settings.textures.push_back({
|
||||||
textures.push_back({
|
|
||||||
"MaterialAlphaMap",
|
"MaterialAlphaMap",
|
||||||
"Alpha",
|
"Alpha",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.diffuse = textures.size();
|
s_textureIndexes.diffuse = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialDiffuseMap",
|
"MaterialDiffuseMap",
|
||||||
"Diffuse",
|
"Diffuse",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = textures.size();
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"TextureOverlay",
|
"TextureOverlay",
|
||||||
"Overlay",
|
"Overlay",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
s_uniformBlockIndex = settings.uniformBlocks.size();
|
||||||
s_uniformBlockIndex = uniformBlocks.size();
|
settings.uniformBlocks.assign({
|
||||||
uniformBlocks.assign({
|
|
||||||
{
|
{
|
||||||
fieldOffsets.GetSize(),
|
fieldOffsets.GetSize(),
|
||||||
"BasicSettings",
|
"BasicSettings",
|
||||||
|
|
@ -154,19 +155,61 @@ namespace Nz
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<MaterialSettings::SharedUniformBlock> sharedUniformBlock;
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
|
||||||
|
settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock());
|
||||||
|
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = settings.textures.size() + settings.uniformBlocks.size() + settings.sharedUniformBlocks.size();
|
||||||
sharedUniformBlock.push_back(PredefinedInstanceData::GetUniformBlock());
|
settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock());
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = textures.size() + uniformBlocks.size() + sharedUniformBlock.size();
|
|
||||||
sharedUniformBlock.push_back(PredefinedViewerData::GetUniformBlock());
|
|
||||||
|
|
||||||
// Shaders
|
// Shaders
|
||||||
MaterialSettings::DefaultShaders defaultShaders;
|
auto& fragmentShader = settings.shaders[UnderlyingCast(ShaderStageType::Fragment)];
|
||||||
defaultShaders[UnderlyingCast(ShaderStageType::Fragment)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Fragment, Nz::ShaderLanguage::NazaraBinary, r_fragmentShader, sizeof(r_fragmentShader));
|
auto& vertexShader = settings.shaders[UnderlyingCast(ShaderStageType::Vertex)];
|
||||||
defaultShaders[UnderlyingCast(ShaderStageType::Vertex)] = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(Nz::ShaderStageType::Vertex, Nz::ShaderLanguage::NazaraBinary, r_vertexShader, sizeof(r_vertexShader));
|
|
||||||
|
|
||||||
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding, std::move(defaultShaders));
|
fragmentShader = std::make_shared<UberShader>(UnserializeShader(r_fragmentShader, sizeof(r_fragmentShader)));
|
||||||
|
vertexShader = std::make_shared<UberShader>(UnserializeShader(r_vertexShader, sizeof(r_vertexShader)));
|
||||||
|
|
||||||
|
// Conditions
|
||||||
|
|
||||||
|
// HasDiffuseMap
|
||||||
|
{
|
||||||
|
std::array<UInt64, ShaderStageTypeCount> shaderConditions;
|
||||||
|
shaderConditions.fill(0);
|
||||||
|
shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("HAS_DIFFUSE_TEXTURE");
|
||||||
|
|
||||||
|
s_conditionIndexes.hasDiffuseMap = settings.conditions.size();
|
||||||
|
settings.conditions.push_back({
|
||||||
|
"HasDiffuseMap",
|
||||||
|
shaderConditions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasAlphaMap
|
||||||
|
{
|
||||||
|
std::array<UInt64, ShaderStageTypeCount> shaderConditions;
|
||||||
|
shaderConditions.fill(0);
|
||||||
|
shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("HAS_ALPHA_TEXTURE");
|
||||||
|
|
||||||
|
s_conditionIndexes.hasAlphaMap = settings.conditions.size();
|
||||||
|
settings.conditions.push_back({
|
||||||
|
"HasAlphaMap",
|
||||||
|
shaderConditions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// AlphaTest
|
||||||
|
{
|
||||||
|
std::array<UInt64, ShaderStageTypeCount> shaderConditions;
|
||||||
|
shaderConditions.fill(0);
|
||||||
|
shaderConditions[UnderlyingCast(ShaderStageType::Fragment)] = fragmentShader->GetConditionFlagByName("ALPHA_TEST");
|
||||||
|
|
||||||
|
s_conditionIndexes.alphaTest = settings.conditions.size();
|
||||||
|
settings.conditions.push_back({
|
||||||
|
"AlphaTest",
|
||||||
|
shaderConditions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
s_materialSettings = std::make_shared<MaterialSettings>(std::move(settings));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -178,6 +221,7 @@ namespace Nz
|
||||||
|
|
||||||
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
|
std::shared_ptr<MaterialSettings> BasicMaterial::s_materialSettings;
|
||||||
std::size_t BasicMaterial::s_uniformBlockIndex;
|
std::size_t BasicMaterial::s_uniformBlockIndex;
|
||||||
|
BasicMaterial::ConditionIndexes BasicMaterial::s_conditionIndexes;
|
||||||
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
|
BasicMaterial::TextureIndexes BasicMaterial::s_textureIndexes;
|
||||||
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
|
BasicMaterial::UniformOffsets BasicMaterial::s_uniformOffsets;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,15 @@ namespace Nz
|
||||||
*/
|
*/
|
||||||
Material::Material(std::shared_ptr<const MaterialSettings> settings) :
|
Material::Material(std::shared_ptr<const MaterialSettings> settings) :
|
||||||
m_settings(std::move(settings)),
|
m_settings(std::move(settings)),
|
||||||
|
m_enabledConditions(0),
|
||||||
m_pipelineUpdated(false),
|
m_pipelineUpdated(false),
|
||||||
m_shadowCastingEnabled(true)
|
m_shadowCastingEnabled(true)
|
||||||
{
|
{
|
||||||
m_pipelineInfo.settings = m_settings;
|
m_pipelineInfo.settings = m_settings;
|
||||||
m_pipelineInfo.shaders = m_settings->GetDefaultShaders();
|
|
||||||
|
const auto& shaders = m_settings->GetShaders();
|
||||||
|
for (std::size_t i = 0; i < ShaderStageTypeCount; ++i)
|
||||||
|
m_pipelineInfo.shaders[i].uberShader = shaders[i];
|
||||||
|
|
||||||
m_textures.resize(m_settings->GetTextures().size());
|
m_textures.resize(m_settings->GetTextures().size());
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <Nazara/Graphics/Material.hpp>
|
#include <Nazara/Graphics/Material.hpp>
|
||||||
#include <Nazara/Graphics/MaterialSettings.hpp>
|
#include <Nazara/Graphics/MaterialSettings.hpp>
|
||||||
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
|
#include <Nazara/Graphics/PhongLightingMaterial.hpp>
|
||||||
|
#include <Nazara/Graphics/UberShader.hpp>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
|
|
@ -47,10 +48,10 @@ namespace Nz
|
||||||
|
|
||||||
renderPipelineInfo.pipelineLayout = m_pipelineInfo.settings->GetRenderPipelineLayout();
|
renderPipelineInfo.pipelineLayout = m_pipelineInfo.settings->GetRenderPipelineLayout();
|
||||||
|
|
||||||
for (const auto& shaderStage : m_pipelineInfo.shaders)
|
for (const auto& shaderEntry : m_pipelineInfo.shaders)
|
||||||
{
|
{
|
||||||
if (shaderStage)
|
if (shaderEntry.uberShader)
|
||||||
renderPipelineInfo.shaderStages.push_back(shaderStage);
|
renderPipelineInfo.shaderStages.push_back(shaderEntry.uberShader->Get(shaderEntry.enabledConditions));
|
||||||
}
|
}
|
||||||
|
|
||||||
renderPipelineInfo.vertexBuffers = vertexBuffers;
|
renderPipelineInfo.vertexBuffers = vertexBuffers;
|
||||||
|
|
|
||||||
|
|
@ -151,8 +151,8 @@ namespace Nz
|
||||||
s_phongUniformOffsets.diffuseColor = phongUniformStruct.AddField(StructFieldType_Float4);
|
s_phongUniformOffsets.diffuseColor = phongUniformStruct.AddField(StructFieldType_Float4);
|
||||||
s_phongUniformOffsets.specularColor = phongUniformStruct.AddField(StructFieldType_Float4);
|
s_phongUniformOffsets.specularColor = phongUniformStruct.AddField(StructFieldType_Float4);
|
||||||
|
|
||||||
MaterialSettings::PredefinedBinding predefinedBinding;
|
MaterialSettings::Builder settings;
|
||||||
predefinedBinding.fill(MaterialSettings::InvalidIndex);
|
settings.predefinedBinding.fill(MaterialSettings::InvalidIndex);
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformVariable> phongVariables;
|
std::vector<MaterialSettings::UniformVariable> phongVariables;
|
||||||
phongVariables.assign({
|
phongVariables.assign({
|
||||||
|
|
@ -187,10 +187,8 @@ namespace Nz
|
||||||
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.alphaThreshold) = 0.2f;
|
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.alphaThreshold) = 0.2f;
|
||||||
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.shininess) = 50.f;
|
AccessByOffset<float&>(defaultValues.data(), s_phongUniformOffsets.shininess) = 50.f;
|
||||||
|
|
||||||
std::vector<MaterialSettings::UniformBlock> uniformBlocks;
|
s_phongUniformBlockIndex = settings.uniformBlocks.size();
|
||||||
|
settings.uniformBlocks.push_back({
|
||||||
s_phongUniformBlockIndex = uniformBlocks.size();
|
|
||||||
uniformBlocks.push_back({
|
|
||||||
phongUniformStruct.GetSize(),
|
phongUniformStruct.GetSize(),
|
||||||
"PhongSettings",
|
"PhongSettings",
|
||||||
"MaterialPhongSettings",
|
"MaterialPhongSettings",
|
||||||
|
|
@ -198,65 +196,63 @@ namespace Nz
|
||||||
std::move(defaultValues)
|
std::move(defaultValues)
|
||||||
});
|
});
|
||||||
|
|
||||||
std::vector<MaterialSettings::SharedUniformBlock> sharedUniformBlock;
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = settings.sharedUniformBlocks.size();
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboInstanceData)] = sharedUniformBlock.size();
|
settings.sharedUniformBlocks.push_back(PredefinedInstanceData::GetUniformBlock());
|
||||||
sharedUniformBlock.push_back(PredefinedInstanceData::GetUniformBlock());
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboLighData)] = settings.sharedUniformBlocks.size();
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboLighData)] = sharedUniformBlock.size();
|
settings.sharedUniformBlocks.push_back(PredefinedLightData::GetUniformBlock());
|
||||||
sharedUniformBlock.push_back(PredefinedLightData::GetUniformBlock());
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = settings.sharedUniformBlocks.size();
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::UboViewerData)] = sharedUniformBlock.size();
|
settings.sharedUniformBlocks.push_back(PredefinedViewerData::GetUniformBlock());
|
||||||
sharedUniformBlock.push_back(PredefinedViewerData::GetUniformBlock());
|
|
||||||
|
|
||||||
std::vector<MaterialSettings::Texture> textures;
|
s_textureIndexes.alpha = settings.textures.size();
|
||||||
s_textureIndexes.alpha = textures.size();
|
settings.textures.push_back({
|
||||||
textures.push_back({
|
|
||||||
"MaterialAlphaMap",
|
"MaterialAlphaMap",
|
||||||
"Alpha",
|
"Alpha",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.diffuse = textures.size();
|
s_textureIndexes.diffuse = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialDiffuseMap",
|
"MaterialDiffuseMap",
|
||||||
"Diffuse",
|
"Diffuse",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.emissive = textures.size();
|
s_textureIndexes.emissive = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialEmissiveMap",
|
"MaterialEmissiveMap",
|
||||||
"Emissive",
|
"Emissive",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.height = textures.size();
|
s_textureIndexes.height = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialHeightMap",
|
"MaterialHeightMap",
|
||||||
"Height",
|
"Height",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.normal = textures.size();
|
s_textureIndexes.normal = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialNormalMap",
|
"MaterialNormalMap",
|
||||||
"Normal",
|
"Normal",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
s_textureIndexes.specular = textures.size();
|
s_textureIndexes.specular = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"MaterialSpecularMap",
|
"MaterialSpecularMap",
|
||||||
"Specular",
|
"Specular",
|
||||||
ImageType_2D
|
ImageType_2D
|
||||||
});
|
});
|
||||||
|
|
||||||
predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = textures.size();
|
settings.predefinedBinding[UnderlyingCast(PredefinedShaderBinding::TexOverlay)] = settings.textures.size();
|
||||||
textures.push_back({
|
settings.textures.push_back({
|
||||||
"TextureOverlay",
|
"TextureOverlay",
|
||||||
"Overlay",
|
"Overlay",
|
||||||
ImageType_2D,
|
ImageType_2D,
|
||||||
});
|
});
|
||||||
|
|
||||||
s_materialSettings = std::make_shared<MaterialSettings>(std::move(textures), std::move(uniformBlocks), std::move(sharedUniformBlock), predefinedBinding, MaterialSettings::DefaultShaders{});
|
s_materialSettings = std::make_shared<MaterialSettings>(std::move(settings));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
78,83,72,82,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,3,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,1,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,1,0,0,0,0,0,0,0,6,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,16,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,0,0,0,0,10,1,0,0,0,0,0,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,1,0,0,0,1,0,0,0,0,14,84,101,120,116,117,114,101,79,118,101,114,108,97,121,0,0,0,0,10,1,0,0,0,2,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,13,0,0,0,3,0,0,0,7,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,5,0,0,0,5,0,0,0,0,191,52,253,244,63,52,253,244,0,0,0,7,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,10,0,0,0,1,0,0,0,2,0,0,0,9,0,0,0,1,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,9,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,11,0,0,0,9,0,0,0,5,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,0,0,0,9,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,84,97,114,103,101,116,48,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,11,0,0,0,9,0,0,0,5,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,0,0,0,9,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,9,0,0,0,2,0,0,0,10,109,97,116,68,105,102,102,117,115,101,0,0,0,0,4,
|
78,83,72,82,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,19,72,65,83,95,68,73,70,70,85,83,69,95,84,69,88,84,85,82,69,0,0,0,17,72,65,83,95,65,76,80,72,65,95,84,69,88,84,85,82,69,0,0,0,10,65,76,80,72,65,95,84,69,83,84,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,4,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,1,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,1,0,0,0,0,0,0,0,6,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,16,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,0,0,0,0,10,1,0,0,0,0,0,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,1,0,0,0,1,0,0,0,0,14,84,101,120,116,117,114,101,79,118,101,114,108,97,121,0,0,0,0,10,1,0,0,0,2,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,15,0,0,0,6,0,0,0,8,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,5,0,0,0,5,0,0,0,0,191,52,253,244,63,52,253,244,0,0,0,8,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,12,0,0,0,1,0,0,0,2,0,0,0,11,0,0,0,1,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,11,0,0,0,2,0,0,0,8,108,105,103,104,116,68,105,114,0,0,0,0,3,0,0,0,8,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,11,0,0,0,2,0,0,0,11,108,105,103,104,116,70,97,99,116,111,114,0,0,0,0,1,0,0,0,6,0,0,0,19,72,65,83,95,68,73,70,70,85,83,69,95,84,69,88,84,85,82,69,0,0,0,2,0,0,0,2,0,0,0,13,0,0,0,11,0,0,0,5,0,0,0,18,77,97,116,101,114,105,97,108,68,105,102,102,117,115,101,77,97,112,0,0,0,0,10,0,0,0,11,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,0,4,0,0,0,1,0,0,0,1,0,0,0,8,0,0,0,2,0,0,0,4,118,97,114,48,0,0,0,0,4,0,0,0,6,0,0,0,17,72,65,83,95,65,76,80,72,65,95,84,69,88,84,85,82,69,0,0,0,4,0,0,0,4,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,1,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,13,0,0,0,11,0,0,0,5,0,0,0,16,77,97,116,101,114,105,97,108,65,108,112,104,97,77,97,112,0,0,0,0,10,0,0,0,11,0,0,0,1,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,0,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,3,0,0,0,11,0,0,0,2,0,0,0,12,116,101,120,116,117,114,101,67,111,108,111,114,0,0,0,0,4,0,0,0,3,0,0,0,1,0,0,0,2,0,0,0,4,0,0,0,6,0,0,0,10,65,76,80,72,65,95,84,69,83,84,0,0,0,2,0,0,0,8,0,0,0,14,0,0,0,0,0,0,0,1,0,0,0,11,0,0,0,2,0,0,0,4,118,97,114,48,0,0,0,0,4,0,0,0,3,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,5,0,0,0,0,0,0,0,0,5,0,0,0,0,1,0,0,0,9,255,255,255,255,0,0,0,10,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,3,0,0,0,13,82,101,110,100,101,114,84,97,114,103,101,116,48,0,0,0,0,4,0,0,0,11,0,0,0,2,0,0,0,4,118,97,114,48,0,0,0,0,4,
|
||||||
Binary file not shown.
|
|
@ -1 +1 @@
|
||||||
78,83,72,82,0,0,0,1,0,0,0,1,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,3,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,3,0,0,0,5,105,110,80,111,115,0,0,0,0,3,1,0,0,0,0,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,1,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,1,0,0,0,2,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,3,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,13,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,9,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,3,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,9,0,0,0,1,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,0,0,0,8,0,0,0,1,0,0,0,0,0,0,0,9,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,9,0,0,0,5,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,9,0,0,0,1,0,0,0,5,105,110,80,111,115,0,0,0,0,3,0,0,0,5,0,0,0,1,63,128,0,0,255,255,255,255,255,255,255,255,
|
78,83,72,82,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,3,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,0,0,0,2,0,0,0,14,65,108,112,104,97,84,104,114,101,115,104,111,108,100,0,0,0,0,1,0,0,0,12,68,105,102,102,117,115,101,67,111,108,111,114,0,0,0,0,4,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,2,0,0,0,11,119,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,105,110,118,87,111,114,108,100,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,9,0,0,0,16,112,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,19,105,110,118,80,114,111,106,101,99,116,105,111,110,77,97,116,114,105,120,0,0,0,0,9,0,0,0,10,118,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,13,105,110,118,86,105,101,119,77,97,116,114,105,120,0,0,0,0,9,0,0,0,14,118,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,17,105,110,118,86,105,101,119,80,114,111,106,77,97,116,114,105,120,0,0,0,0,9,0,0,0,16,114,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,19,105,110,118,82,101,110,100,101,114,84,97,114,103,101,116,83,105,122,101,0,0,0,0,2,0,0,0,11,101,121,101,80,111,115,105,116,105,111,110,0,0,0,0,3,0,0,0,3,0,0,0,5,105,110,80,111,115,0,0,0,0,3,1,0,0,0,0,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,1,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,1,0,0,0,2,0,0,0,2,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,1,0,0,0,0,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,1,0,0,0,1,0,0,0,3,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,1,0,0,0,5,1,0,0,0,0,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,4,1,0,0,0,0,0,0,0,8,115,101,116,116,105,110,103,115,1,0,0,0,13,66,97,115,105,99,83,101,116,116,105,110,103,115,1,0,0,0,3,1,0,0,0,0,0,0,0,1,0,0,0,4,109,97,105,110,0,0,0,11,0,0,0,0,0,0,0,15,0,0,0,3,0,0,0,10,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,3,0,0,0,6,118,101,114,116,85,86,0,0,0,0,2,0,0,0,11,0,0,0,1,0,0,0,10,105,110,84,101,120,67,111,111,114,100,0,0,0,0,2,0,0,0,10,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,3,0,0,0,10,118,101,114,116,78,111,114,109,97,108,0,0,0,0,3,0,0,0,11,0,0,0,1,0,0,0,9,105,110,78,111,114,109,97,108,115,0,0,0,0,3,0,0,0,10,0,0,0,1,0,0,0,0,0,0,0,11,0,0,0,0,0,0,0,0,0,0,0,0,4,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,10,118,105,101,119,101,114,68,97,116,97,1,0,0,0,10,86,105,101,119,101,114,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,11,0,0,0,5,0,0,0,12,105,110,115,116,97,110,99,101,68,97,116,97,1,0,0,0,12,73,110,115,116,97,110,99,101,68,97,116,97,0,0,0,0,9,0,0,0,1,0,0,0,0,0,0,0,4,0,0,0,4,0,0,0,11,0,0,0,1,0,0,0,5,105,110,80,111,115,0,0,0,0,3,0,0,0,5,0,0,0,1,63,128,0,0,255,255,255,255,255,255,255,255,
|
||||||
|
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright (C) 2017 Jérôme Leclercq
|
||||||
|
// 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/UberShader.hpp>
|
||||||
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
|
#include <Nazara/Renderer/RenderDevice.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderAst.hpp>
|
||||||
|
#include <limits>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace Nz
|
||||||
|
{
|
||||||
|
UberShader::UberShader(ShaderAst shaderAst) :
|
||||||
|
m_shaderAst(std::move(shaderAst))
|
||||||
|
{
|
||||||
|
std::size_t conditionCount = m_shaderAst.GetConditionCount();
|
||||||
|
|
||||||
|
if (conditionCount >= 64)
|
||||||
|
throw std::runtime_error("Too many conditions");
|
||||||
|
|
||||||
|
m_combinationMask = std::numeric_limits<UInt64>::max();
|
||||||
|
m_combinationMask <<= conditionCount;
|
||||||
|
m_combinationMask = ~m_combinationMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt64 UberShader::GetConditionFlagByName(const std::string_view& condition) const
|
||||||
|
{
|
||||||
|
std::size_t conditionIndex = m_shaderAst.FindConditionByName(condition);
|
||||||
|
if (conditionIndex != ShaderAst::InvalidCondition)
|
||||||
|
return SetBit<UInt64>(0, conditionIndex);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<ShaderStage>& UberShader::Get(UInt64 combination)
|
||||||
|
{
|
||||||
|
combination &= m_combinationMask;
|
||||||
|
|
||||||
|
auto it = m_combinations.find(combination);
|
||||||
|
if (it == m_combinations.end())
|
||||||
|
{
|
||||||
|
ShaderWriter::States states;
|
||||||
|
states.enabledConditions = combination;
|
||||||
|
|
||||||
|
std::shared_ptr<ShaderStage> stage = Graphics::Instance()->GetRenderDevice().InstantiateShaderStage(m_shaderAst, std::move(states));
|
||||||
|
|
||||||
|
it = m_combinations.emplace(combination, std::move(stage)).first;
|
||||||
|
}
|
||||||
|
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -93,6 +93,7 @@ namespace Nz
|
||||||
command.framebuffer->Activate();
|
command.framebuffer->Activate();
|
||||||
|
|
||||||
context = GL::Context::GetCurrentContext();
|
context = GL::Context::GetCurrentContext();
|
||||||
|
context->glClearColor(0.5, 0.5, 0.5, 1.0);
|
||||||
context->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
context->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,11 @@ namespace Nz
|
||||||
return std::make_shared<OpenGLRenderPipelineLayout>(std::move(pipelineLayoutInfo));
|
return std::make_shared<OpenGLRenderPipelineLayout>(std::move(pipelineLayoutInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ShaderStage> OpenGLDevice::InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states)
|
||||||
|
{
|
||||||
|
return std::make_shared<OpenGLShaderStage>(*this, shaderAst, states);
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ShaderStage> OpenGLDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
std::shared_ptr<ShaderStage> OpenGLDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||||
{
|
{
|
||||||
return std::make_shared<OpenGLShaderStage>(*this, type, lang, source, sourceSize);
|
return std::make_shared<OpenGLShaderStage>(*this, type, lang, source, sourceSize);
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ namespace Nz
|
||||||
const auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, i);
|
const auto& textureDescriptor = m_owner.GetTextureDescriptor(m_poolIndex, m_bindingIndex, i);
|
||||||
|
|
||||||
UInt32 textureIndex = textureDescriptor.bindingIndex;
|
UInt32 textureIndex = textureDescriptor.bindingIndex;
|
||||||
|
if (textureIndex == OpenGLRenderPipelineLayout::InvalidIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
context.BindSampler(textureIndex, textureDescriptor.sampler);
|
context.BindSampler(textureIndex, textureDescriptor.sampler);
|
||||||
context.BindTexture(textureIndex, textureDescriptor.textureTarget, textureDescriptor.texture);
|
context.BindTexture(textureIndex, textureDescriptor.textureTarget, textureDescriptor.texture);
|
||||||
|
|
@ -29,6 +31,10 @@ namespace Nz
|
||||||
{
|
{
|
||||||
const auto& uboDescriptor = m_owner.GetUniformBufferDescriptor(m_poolIndex, m_bindingIndex, i);
|
const auto& uboDescriptor = m_owner.GetUniformBufferDescriptor(m_poolIndex, m_bindingIndex, i);
|
||||||
|
|
||||||
|
UInt32 uboIndex = uboDescriptor.bindingIndex;
|
||||||
|
if (uboIndex == OpenGLRenderPipelineLayout::InvalidIndex)
|
||||||
|
continue;
|
||||||
|
|
||||||
context.BindUniformBuffer(uboDescriptor.bindingIndex, uboDescriptor.buffer, uboDescriptor.offset, uboDescriptor.size);
|
context.BindUniformBuffer(uboDescriptor.bindingIndex, uboDescriptor.buffer, uboDescriptor.offset, uboDescriptor.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,15 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
OpenGLShaderStage::OpenGLShaderStage(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states)
|
||||||
|
{
|
||||||
|
if (!m_shader.Create(device, ToOpenGL(shaderAst.GetStage())))
|
||||||
|
throw std::runtime_error("failed to create shader"); //< TODO: Handle error message
|
||||||
|
|
||||||
|
Create(device, shaderAst, states);
|
||||||
|
CheckCompilationStatus();
|
||||||
|
}
|
||||||
|
|
||||||
OpenGLShaderStage::OpenGLShaderStage(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
OpenGLShaderStage::OpenGLShaderStage(OpenGLDevice& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||||
{
|
{
|
||||||
if (!m_shader.Create(device, ToOpenGL(type)))
|
if (!m_shader.Create(device, ToOpenGL(type)))
|
||||||
|
|
@ -28,32 +37,11 @@ namespace Nz
|
||||||
|
|
||||||
case ShaderLanguage::NazaraBinary:
|
case ShaderLanguage::NazaraBinary:
|
||||||
{
|
{
|
||||||
ByteStream byteStream(source, sourceSize);
|
auto shader = UnserializeShader(source, sourceSize);
|
||||||
auto shader = Nz::UnserializeShader(byteStream);
|
|
||||||
|
|
||||||
if (shader.GetStage() != type)
|
if (shader.GetStage() != type)
|
||||||
throw std::runtime_error("incompatible shader stage");
|
throw std::runtime_error("incompatible shader stage");
|
||||||
|
|
||||||
const auto& context = device.GetReferenceContext();
|
Create(device, shader, {});
|
||||||
const auto& contextParams = context.GetParams();
|
|
||||||
|
|
||||||
GlslWriter::Environment env;
|
|
||||||
env.glES = (contextParams.type == GL::ContextType::OpenGL_ES);
|
|
||||||
env.glMajorVersion = contextParams.glMajorVersion;
|
|
||||||
env.glMinorVersion = contextParams.glMinorVersion;
|
|
||||||
env.extCallback = [&](const std::string_view& ext)
|
|
||||||
{
|
|
||||||
return context.IsExtensionSupported(std::string(ext));
|
|
||||||
};
|
|
||||||
env.flipYPosition = true;
|
|
||||||
|
|
||||||
GlslWriter writer;
|
|
||||||
writer.SetEnv(env);
|
|
||||||
|
|
||||||
std::string code = writer.Generate(shader);
|
|
||||||
|
|
||||||
m_shader.SetSource(code.data(), code.size());
|
|
||||||
m_shader.Compile();
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,8 +59,39 @@ namespace Nz
|
||||||
throw std::runtime_error("Unsupported shader language");
|
throw std::runtime_error("Unsupported shader language");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CheckCompilationStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OpenGLShaderStage::CheckCompilationStatus()
|
||||||
|
{
|
||||||
std::string errorLog;
|
std::string errorLog;
|
||||||
if (!m_shader.GetCompilationStatus(&errorLog))
|
if (!m_shader.GetCompilationStatus(&errorLog))
|
||||||
throw std::runtime_error("Failed to compile shader: " + errorLog);
|
throw std::runtime_error("Failed to compile shader: " + errorLog);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenGLShaderStage::Create(OpenGLDevice& device, const ShaderAst& shaderAst, const ShaderWriter::States& states)
|
||||||
|
{
|
||||||
|
const auto& context = device.GetReferenceContext();
|
||||||
|
const auto& contextParams = context.GetParams();
|
||||||
|
|
||||||
|
GlslWriter::Environment env;
|
||||||
|
env.glES = (contextParams.type == GL::ContextType::OpenGL_ES);
|
||||||
|
env.glMajorVersion = contextParams.glMajorVersion;
|
||||||
|
env.glMinorVersion = contextParams.glMinorVersion;
|
||||||
|
env.extCallback = [&](const std::string_view& ext)
|
||||||
|
{
|
||||||
|
return context.IsExtensionSupported(std::string(ext));
|
||||||
|
};
|
||||||
|
env.flipYPosition = true;
|
||||||
|
|
||||||
|
GlslWriter writer;
|
||||||
|
writer.SetEnv(env);
|
||||||
|
|
||||||
|
std::string code = writer.Generate(shaderAst, states);
|
||||||
|
|
||||||
|
NazaraError(code);
|
||||||
|
|
||||||
|
m_shader.SetSource(code.data(), code.size());
|
||||||
|
m_shader.Compile();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -174,7 +174,7 @@ namespace Nz::GL
|
||||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB
|
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB
|
||||||
};
|
};
|
||||||
|
|
||||||
m_handle = baseContext->wglCreateContextAttribsARB(m_deviceContext, nullptr, attributes.data());
|
m_handle = baseContext->wglCreateContextAttribsARB(m_deviceContext, (shareContext) ? shareContext->m_handle : nullptr, attributes.data());
|
||||||
if (m_handle)
|
if (m_handle)
|
||||||
{
|
{
|
||||||
m_params.type = ContextType::OpenGL;
|
m_params.type = ContextType::OpenGL;
|
||||||
|
|
@ -198,16 +198,16 @@ namespace Nz::GL
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_params.type = ContextType::OpenGL;
|
if (shareContext)
|
||||||
}
|
|
||||||
|
|
||||||
if (shareContext)
|
|
||||||
{
|
|
||||||
if (!m_loader.wglShareLists(shareContext->m_handle, m_handle))
|
|
||||||
{
|
{
|
||||||
NazaraError("failed to share context objects: " + Error::GetLastSystemError());
|
if (!m_loader.wglShareLists(shareContext->m_handle, m_handle))
|
||||||
return false;
|
{
|
||||||
|
NazaraError("failed to share context objects: " + Error::GetLastSystemError());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_params.type = ContextType::OpenGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadWGLExt();
|
LoadWGLExt();
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Nz
|
||||||
|
|
||||||
float Arbiter2D::GetContactDepth(std::size_t i) const
|
float Arbiter2D::GetContactDepth(std::size_t i) const
|
||||||
{
|
{
|
||||||
return cpArbiterGetDepth(m_arbiter, int(i));
|
return float(cpArbiterGetDepth(m_arbiter, int(i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::Vector2f Arbiter2D::GetContactPointA(std::size_t i) const
|
Nz::Vector2f Arbiter2D::GetContactPointA(std::size_t i) const
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <Nazara/Shader/GlslWriter.hpp>
|
#include <Nazara/Shader/GlslWriter.hpp>
|
||||||
#include <Nazara/Core/Algorithm.hpp>
|
#include <Nazara/Core/Algorithm.hpp>
|
||||||
#include <Nazara/Core/CallOnExit.hpp>
|
#include <Nazara/Core/CallOnExit.hpp>
|
||||||
|
#include <Nazara/Math/Algorithm.hpp>
|
||||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
#include <Nazara/Shader/ShaderAstCloner.hpp>
|
#include <Nazara/Shader/ShaderAstCloner.hpp>
|
||||||
#include <Nazara/Shader/ShaderAstValidator.hpp>
|
#include <Nazara/Shader/ShaderAstValidator.hpp>
|
||||||
|
|
@ -418,21 +419,17 @@ namespace Nz
|
||||||
|
|
||||||
switch (node.op)
|
switch (node.op)
|
||||||
{
|
{
|
||||||
case ShaderNodes::BinaryType::Add:
|
case ShaderNodes::BinaryType::Add: Append(" + "); break;
|
||||||
Append(" + ");
|
case ShaderNodes::BinaryType::Substract: Append(" - "); break;
|
||||||
break;
|
case ShaderNodes::BinaryType::Multiply: Append(" * "); break;
|
||||||
case ShaderNodes::BinaryType::Substract:
|
case ShaderNodes::BinaryType::Divide: Append(" / "); break;
|
||||||
Append(" - ");
|
|
||||||
break;
|
case ShaderNodes::BinaryType::CompEq: Append(" == "); break;
|
||||||
case ShaderNodes::BinaryType::Multiply:
|
case ShaderNodes::BinaryType::CompGe: Append(" >= "); break;
|
||||||
Append(" * ");
|
case ShaderNodes::BinaryType::CompGt: Append(" > "); break;
|
||||||
break;
|
case ShaderNodes::BinaryType::CompLe: Append(" <= "); break;
|
||||||
case ShaderNodes::BinaryType::Divide:
|
case ShaderNodes::BinaryType::CompLt: Append(" < "); break;
|
||||||
Append(" / ");
|
case ShaderNodes::BinaryType::CompNe: Append(" != "); break;
|
||||||
break;
|
|
||||||
case ShaderNodes::BinaryType::Equality:
|
|
||||||
Append(" == ");
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Visit(node.right, true);
|
Visit(node.right, true);
|
||||||
|
|
@ -448,15 +445,17 @@ namespace Nz
|
||||||
Append(node.exprType);
|
Append(node.exprType);
|
||||||
Append("(");
|
Append("(");
|
||||||
|
|
||||||
for (std::size_t i = 0; node.expressions[i]; ++i)
|
bool first = true;
|
||||||
|
for (const auto& exprPtr : node.expressions)
|
||||||
{
|
{
|
||||||
if (i != 0)
|
if (!exprPtr)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!first)
|
||||||
m_currentState->stream << ", ";
|
m_currentState->stream << ", ";
|
||||||
|
|
||||||
const auto& exprPtr = node.expressions[i];
|
|
||||||
NazaraAssert(exprPtr, "Invalid expression");
|
|
||||||
|
|
||||||
Visit(exprPtr);
|
Visit(exprPtr);
|
||||||
|
first = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Append(")");
|
Append(")");
|
||||||
|
|
@ -465,7 +464,10 @@ namespace Nz
|
||||||
|
|
||||||
void GlslWriter::Visit(ShaderNodes::ConditionalExpression& node)
|
void GlslWriter::Visit(ShaderNodes::ConditionalExpression& node)
|
||||||
{
|
{
|
||||||
if (m_context.states->enabledConditions.count(node.conditionName) != 0)
|
std::size_t conditionIndex = m_context.shader->FindConditionByName(node.conditionName);
|
||||||
|
assert(conditionIndex != ShaderAst::InvalidCondition);
|
||||||
|
|
||||||
|
if (TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex))
|
||||||
Visit(node.truePath);
|
Visit(node.truePath);
|
||||||
else
|
else
|
||||||
Visit(node.falsePath);
|
Visit(node.falsePath);
|
||||||
|
|
@ -473,7 +475,10 @@ namespace Nz
|
||||||
|
|
||||||
void GlslWriter::Visit(ShaderNodes::ConditionalStatement& node)
|
void GlslWriter::Visit(ShaderNodes::ConditionalStatement& node)
|
||||||
{
|
{
|
||||||
if (m_context.states->enabledConditions.count(node.conditionName) != 0)
|
std::size_t conditionIndex = m_context.shader->FindConditionByName(node.conditionName);
|
||||||
|
assert(conditionIndex != ShaderAst::InvalidCondition);
|
||||||
|
|
||||||
|
if (TestBit<Nz::UInt64>(m_context.states->enabledConditions, conditionIndex))
|
||||||
Visit(node.statement);
|
Visit(node.statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -604,7 +609,7 @@ namespace Nz
|
||||||
|
|
||||||
void GlslWriter::Visit(ShaderNodes::SwizzleOp& node)
|
void GlslWriter::Visit(ShaderNodes::SwizzleOp& node)
|
||||||
{
|
{
|
||||||
Visit(node.expression);
|
Visit(node.expression, true);
|
||||||
Append(".");
|
Append(".");
|
||||||
|
|
||||||
for (std::size_t i = 0; i < node.componentCount; ++i)
|
for (std::size_t i = 0; i < node.componentCount; ++i)
|
||||||
|
|
|
||||||
|
|
@ -659,6 +659,9 @@ namespace Nz
|
||||||
Int32 nodeTypeInt;
|
Int32 nodeTypeInt;
|
||||||
m_stream >> nodeTypeInt;
|
m_stream >> nodeTypeInt;
|
||||||
|
|
||||||
|
if (nodeTypeInt < static_cast<Int32>(ShaderNodes::NodeType::None) || nodeTypeInt > static_cast<Int32>(ShaderNodes::NodeType::Max))
|
||||||
|
throw std::runtime_error("invalid node type");
|
||||||
|
|
||||||
ShaderNodes::NodeType nodeType = static_cast<ShaderNodes::NodeType>(nodeTypeInt);
|
ShaderNodes::NodeType nodeType = static_cast<ShaderNodes::NodeType>(nodeTypeInt);
|
||||||
|
|
||||||
#define HandleType(Type) case ShaderNodes::NodeType:: Type : node = std::make_shared<ShaderNodes:: Type>(); break
|
#define HandleType(Type) case ShaderNodes::NodeType:: Type : node = std::make_shared<ShaderNodes:: Type>(); break
|
||||||
|
|
|
||||||
|
|
@ -150,8 +150,17 @@ namespace Nz
|
||||||
|
|
||||||
switch (node.op)
|
switch (node.op)
|
||||||
{
|
{
|
||||||
|
case ShaderNodes::BinaryType::CompGe:
|
||||||
|
case ShaderNodes::BinaryType::CompGt:
|
||||||
|
case ShaderNodes::BinaryType::CompLe:
|
||||||
|
case ShaderNodes::BinaryType::CompLt:
|
||||||
|
if (leftType == ShaderNodes::BasicType::Boolean)
|
||||||
|
throw AstError{ "this operation is not supported for booleans" };
|
||||||
|
|
||||||
|
[[fallthrough]];
|
||||||
case ShaderNodes::BinaryType::Add:
|
case ShaderNodes::BinaryType::Add:
|
||||||
case ShaderNodes::BinaryType::Equality:
|
case ShaderNodes::BinaryType::CompEq:
|
||||||
|
case ShaderNodes::BinaryType::CompNe:
|
||||||
case ShaderNodes::BinaryType::Substract:
|
case ShaderNodes::BinaryType::Substract:
|
||||||
TypeMustMatch(node.left, node.right);
|
TypeMustMatch(node.left, node.right);
|
||||||
break;
|
break;
|
||||||
|
|
@ -236,7 +245,7 @@ namespace Nz
|
||||||
}
|
}
|
||||||
|
|
||||||
if (componentCount != requiredComponents)
|
if (componentCount != requiredComponents)
|
||||||
throw AstError{ "Component count doesn't match required component count" };
|
throw AstError{ "component count doesn't match required component count" };
|
||||||
|
|
||||||
ShaderAstRecursiveVisitor::Visit(node);
|
ShaderAstRecursiveVisitor::Visit(node);
|
||||||
}
|
}
|
||||||
|
|
@ -246,28 +255,16 @@ namespace Nz
|
||||||
MandatoryNode(node.truePath);
|
MandatoryNode(node.truePath);
|
||||||
MandatoryNode(node.falsePath);
|
MandatoryNode(node.falsePath);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < m_shader.GetConditionCount(); ++i)
|
if (m_shader.FindConditionByName(node.conditionName) == ShaderAst::InvalidCondition)
|
||||||
{
|
throw AstError{ "condition not found" };
|
||||||
const auto& condition = m_shader.GetCondition(i);
|
|
||||||
if (condition.name == node.conditionName)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw AstError{ "Condition not found" };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderAstValidator::Visit(ShaderNodes::ConditionalStatement& node)
|
void ShaderAstValidator::Visit(ShaderNodes::ConditionalStatement& node)
|
||||||
{
|
{
|
||||||
MandatoryNode(node.statement);
|
MandatoryNode(node.statement);
|
||||||
|
|
||||||
for (std::size_t i = 0; i < m_shader.GetConditionCount(); ++i)
|
if (m_shader.FindConditionByName(node.conditionName) == ShaderAst::InvalidCondition)
|
||||||
{
|
throw AstError{ "condition not found" };
|
||||||
const auto& condition = m_shader.GetCondition(i);
|
|
||||||
if (condition.name == node.conditionName)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw AstError{ "Condition not found" };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShaderAstValidator::Visit(ShaderNodes::Constant& /*node*/)
|
void ShaderAstValidator::Visit(ShaderNodes::Constant& /*node*/)
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,12 @@ namespace Nz::ShaderNodes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case BinaryType::Equality:
|
case BinaryType::CompEq:
|
||||||
|
case BinaryType::CompGe:
|
||||||
|
case BinaryType::CompGt:
|
||||||
|
case BinaryType::CompLe:
|
||||||
|
case BinaryType::CompLt:
|
||||||
|
case BinaryType::CompNe:
|
||||||
exprType = BasicType::Boolean;
|
exprType = BasicType::Boolean;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ namespace Nz
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case ShaderNodes::BinaryType::Equality:
|
case ShaderNodes::BinaryType::CompEq:
|
||||||
{
|
{
|
||||||
switch (leftType)
|
switch (leftType)
|
||||||
{
|
{
|
||||||
|
|
@ -185,6 +185,166 @@ namespace Nz
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ShaderNodes::BinaryType::CompGe:
|
||||||
|
{
|
||||||
|
switch (leftType)
|
||||||
|
{
|
||||||
|
case ShaderNodes::BasicType::Float1:
|
||||||
|
case ShaderNodes::BasicType::Float2:
|
||||||
|
case ShaderNodes::BasicType::Float3:
|
||||||
|
case ShaderNodes::BasicType::Float4:
|
||||||
|
case ShaderNodes::BasicType::Mat4x4:
|
||||||
|
return SpirvOp::OpFOrdGreaterThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Int1:
|
||||||
|
case ShaderNodes::BasicType::Int2:
|
||||||
|
case ShaderNodes::BasicType::Int3:
|
||||||
|
case ShaderNodes::BasicType::Int4:
|
||||||
|
return SpirvOp::OpSGreaterThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::UInt1:
|
||||||
|
case ShaderNodes::BasicType::UInt2:
|
||||||
|
case ShaderNodes::BasicType::UInt3:
|
||||||
|
case ShaderNodes::BasicType::UInt4:
|
||||||
|
return SpirvOp::OpUGreaterThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Boolean:
|
||||||
|
case ShaderNodes::BasicType::Sampler2D:
|
||||||
|
case ShaderNodes::BasicType::Void:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ShaderNodes::BinaryType::CompGt:
|
||||||
|
{
|
||||||
|
switch (leftType)
|
||||||
|
{
|
||||||
|
case ShaderNodes::BasicType::Float1:
|
||||||
|
case ShaderNodes::BasicType::Float2:
|
||||||
|
case ShaderNodes::BasicType::Float3:
|
||||||
|
case ShaderNodes::BasicType::Float4:
|
||||||
|
case ShaderNodes::BasicType::Mat4x4:
|
||||||
|
return SpirvOp::OpFOrdGreaterThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Int1:
|
||||||
|
case ShaderNodes::BasicType::Int2:
|
||||||
|
case ShaderNodes::BasicType::Int3:
|
||||||
|
case ShaderNodes::BasicType::Int4:
|
||||||
|
return SpirvOp::OpSGreaterThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::UInt1:
|
||||||
|
case ShaderNodes::BasicType::UInt2:
|
||||||
|
case ShaderNodes::BasicType::UInt3:
|
||||||
|
case ShaderNodes::BasicType::UInt4:
|
||||||
|
return SpirvOp::OpUGreaterThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Boolean:
|
||||||
|
case ShaderNodes::BasicType::Sampler2D:
|
||||||
|
case ShaderNodes::BasicType::Void:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ShaderNodes::BinaryType::CompLe:
|
||||||
|
{
|
||||||
|
switch (leftType)
|
||||||
|
{
|
||||||
|
case ShaderNodes::BasicType::Float1:
|
||||||
|
case ShaderNodes::BasicType::Float2:
|
||||||
|
case ShaderNodes::BasicType::Float3:
|
||||||
|
case ShaderNodes::BasicType::Float4:
|
||||||
|
case ShaderNodes::BasicType::Mat4x4:
|
||||||
|
return SpirvOp::OpFOrdLessThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Int1:
|
||||||
|
case ShaderNodes::BasicType::Int2:
|
||||||
|
case ShaderNodes::BasicType::Int3:
|
||||||
|
case ShaderNodes::BasicType::Int4:
|
||||||
|
return SpirvOp::OpSLessThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::UInt1:
|
||||||
|
case ShaderNodes::BasicType::UInt2:
|
||||||
|
case ShaderNodes::BasicType::UInt3:
|
||||||
|
case ShaderNodes::BasicType::UInt4:
|
||||||
|
return SpirvOp::OpULessThanEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Boolean:
|
||||||
|
case ShaderNodes::BasicType::Sampler2D:
|
||||||
|
case ShaderNodes::BasicType::Void:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ShaderNodes::BinaryType::CompLt:
|
||||||
|
{
|
||||||
|
switch (leftType)
|
||||||
|
{
|
||||||
|
case ShaderNodes::BasicType::Float1:
|
||||||
|
case ShaderNodes::BasicType::Float2:
|
||||||
|
case ShaderNodes::BasicType::Float3:
|
||||||
|
case ShaderNodes::BasicType::Float4:
|
||||||
|
case ShaderNodes::BasicType::Mat4x4:
|
||||||
|
return SpirvOp::OpFOrdLessThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Int1:
|
||||||
|
case ShaderNodes::BasicType::Int2:
|
||||||
|
case ShaderNodes::BasicType::Int3:
|
||||||
|
case ShaderNodes::BasicType::Int4:
|
||||||
|
return SpirvOp::OpSLessThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::UInt1:
|
||||||
|
case ShaderNodes::BasicType::UInt2:
|
||||||
|
case ShaderNodes::BasicType::UInt3:
|
||||||
|
case ShaderNodes::BasicType::UInt4:
|
||||||
|
return SpirvOp::OpULessThan;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Boolean:
|
||||||
|
case ShaderNodes::BasicType::Sampler2D:
|
||||||
|
case ShaderNodes::BasicType::Void:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ShaderNodes::BinaryType::CompNe:
|
||||||
|
{
|
||||||
|
switch (leftType)
|
||||||
|
{
|
||||||
|
case ShaderNodes::BasicType::Boolean:
|
||||||
|
return SpirvOp::OpLogicalNotEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Float1:
|
||||||
|
case ShaderNodes::BasicType::Float2:
|
||||||
|
case ShaderNodes::BasicType::Float3:
|
||||||
|
case ShaderNodes::BasicType::Float4:
|
||||||
|
case ShaderNodes::BasicType::Mat4x4:
|
||||||
|
return SpirvOp::OpFOrdNotEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Int1:
|
||||||
|
case ShaderNodes::BasicType::Int2:
|
||||||
|
case ShaderNodes::BasicType::Int3:
|
||||||
|
case ShaderNodes::BasicType::Int4:
|
||||||
|
case ShaderNodes::BasicType::UInt1:
|
||||||
|
case ShaderNodes::BasicType::UInt2:
|
||||||
|
case ShaderNodes::BasicType::UInt3:
|
||||||
|
case ShaderNodes::BasicType::UInt4:
|
||||||
|
return SpirvOp::OpINotEqual;
|
||||||
|
|
||||||
|
case ShaderNodes::BasicType::Sampler2D:
|
||||||
|
case ShaderNodes::BasicType::Void:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ShaderNodes::BinaryType::Multiply:
|
case ShaderNodes::BinaryType::Multiply:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,8 @@ namespace Nz
|
||||||
using LocalContainer = std::unordered_set<std::shared_ptr<const ShaderNodes::LocalVariable>>;
|
using LocalContainer = std::unordered_set<std::shared_ptr<const ShaderNodes::LocalVariable>>;
|
||||||
using ParameterContainer = std::unordered_set< std::shared_ptr<const ShaderNodes::ParameterVariable>>;
|
using ParameterContainer = std::unordered_set< std::shared_ptr<const ShaderNodes::ParameterVariable>>;
|
||||||
|
|
||||||
PreVisitor(const SpirvWriter::States& conditions, SpirvConstantCache& constantCache) :
|
PreVisitor(const ShaderAst& shader, const SpirvWriter::States& conditions, SpirvConstantCache& constantCache) :
|
||||||
|
m_shader(shader),
|
||||||
m_conditions(conditions),
|
m_conditions(conditions),
|
||||||
m_constantCache(constantCache)
|
m_constantCache(constantCache)
|
||||||
{
|
{
|
||||||
|
|
@ -52,7 +53,10 @@ namespace Nz
|
||||||
|
|
||||||
void Visit(ShaderNodes::ConditionalExpression& node) override
|
void Visit(ShaderNodes::ConditionalExpression& node) override
|
||||||
{
|
{
|
||||||
if (m_conditions.enabledConditions.count(node.conditionName) != 0)
|
std::size_t conditionIndex = m_shader.FindConditionByName(node.conditionName);
|
||||||
|
assert(conditionIndex != ShaderAst::InvalidCondition);
|
||||||
|
|
||||||
|
if (TestBit<Nz::UInt64>(m_conditions.enabledConditions, conditionIndex))
|
||||||
Visit(node.truePath);
|
Visit(node.truePath);
|
||||||
else
|
else
|
||||||
Visit(node.falsePath);
|
Visit(node.falsePath);
|
||||||
|
|
@ -60,7 +64,10 @@ namespace Nz
|
||||||
|
|
||||||
void Visit(ShaderNodes::ConditionalStatement& node) override
|
void Visit(ShaderNodes::ConditionalStatement& node) override
|
||||||
{
|
{
|
||||||
if (m_conditions.enabledConditions.count(node.conditionName) != 0)
|
std::size_t conditionIndex = m_shader.FindConditionByName(node.conditionName);
|
||||||
|
assert(conditionIndex != ShaderAst::InvalidCondition);
|
||||||
|
|
||||||
|
if (TestBit<Nz::UInt64>(m_conditions.enabledConditions, conditionIndex))
|
||||||
Visit(node.statement);
|
Visit(node.statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -141,6 +148,7 @@ namespace Nz
|
||||||
ParameterContainer paramVars;
|
ParameterContainer paramVars;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
const ShaderAst& m_shader;
|
||||||
const SpirvWriter::States& m_conditions;
|
const SpirvWriter::States& m_conditions;
|
||||||
SpirvConstantCache& m_constantCache;
|
SpirvConstantCache& m_constantCache;
|
||||||
};
|
};
|
||||||
|
|
@ -229,7 +237,7 @@ namespace Nz
|
||||||
|
|
||||||
ShaderAstCloner cloner;
|
ShaderAstCloner cloner;
|
||||||
|
|
||||||
PreVisitor preVisitor(conditions, state.constantTypeCache);
|
PreVisitor preVisitor(shader, conditions, state.constantTypeCache);
|
||||||
for (const auto& func : shader.GetFunctions())
|
for (const auto& func : shader.GetFunctions())
|
||||||
{
|
{
|
||||||
functionStatements.emplace_back(cloner.Clone(func.statement));
|
functionStatements.emplace_back(cloner.Clone(func.statement));
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,15 @@ namespace Nz
|
||||||
return pipelineLayout;
|
return pipelineLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ShaderStage> VulkanDevice::InstantiateShaderStage(const ShaderAst& shaderAst, const ShaderWriter::States& states)
|
||||||
|
{
|
||||||
|
auto stage = std::make_shared<VulkanShaderStage>();
|
||||||
|
if (!stage->Create(*this, shaderAst, states))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return stage;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ShaderStage> VulkanDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
std::shared_ptr<ShaderStage> VulkanDevice::InstantiateShaderStage(ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||||
{
|
{
|
||||||
auto stage = std::make_shared<VulkanShaderStage>();
|
auto stage = std::make_shared<VulkanShaderStage>();
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,26 @@
|
||||||
|
|
||||||
namespace Nz
|
namespace Nz
|
||||||
{
|
{
|
||||||
|
bool VulkanShaderStage::Create(Vk::Device& device, const ShaderAst& shader, const ShaderWriter::States& states)
|
||||||
|
{
|
||||||
|
m_stage = shader.GetStage();
|
||||||
|
|
||||||
|
SpirvWriter::Environment env;
|
||||||
|
|
||||||
|
SpirvWriter writer;
|
||||||
|
writer.SetEnv(env);
|
||||||
|
|
||||||
|
std::vector<UInt32> code = writer.Generate(shader, states);
|
||||||
|
|
||||||
|
if (!m_shaderModule.Create(device, code.data(), code.size() * sizeof(UInt32)))
|
||||||
|
{
|
||||||
|
NazaraError("Failed to create shader module");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool VulkanShaderStage::Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
bool VulkanShaderStage::Create(Vk::Device& device, ShaderStageType type, ShaderLanguage lang, const void* source, std::size_t sourceSize)
|
||||||
{
|
{
|
||||||
m_stage = type;
|
m_stage = type;
|
||||||
|
|
@ -18,24 +38,12 @@ namespace Nz
|
||||||
{
|
{
|
||||||
case ShaderLanguage::NazaraBinary:
|
case ShaderLanguage::NazaraBinary:
|
||||||
{
|
{
|
||||||
ByteStream byteStream(source, sourceSize);
|
auto shader = UnserializeShader(source, sourceSize);
|
||||||
auto shader = Nz::UnserializeShader(byteStream);
|
|
||||||
|
|
||||||
if (shader.GetStage() != type)
|
if (shader.GetStage() != type)
|
||||||
throw std::runtime_error("incompatible shader stage");
|
throw std::runtime_error("incompatible shader stage");
|
||||||
|
|
||||||
SpirvWriter::Environment env;
|
if (!Create(device, shader, {}))
|
||||||
|
|
||||||
SpirvWriter writer;
|
|
||||||
writer.SetEnv(env);
|
|
||||||
|
|
||||||
std::vector<UInt32> code = writer.Generate(shader);
|
|
||||||
|
|
||||||
if (!m_shaderModule.Create(device, code.data(), code.size() * sizeof(UInt32)))
|
|
||||||
{
|
|
||||||
NazaraError("Failed to create shader module");
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,11 @@ namespace Nz
|
||||||
ss << "[Validation]";
|
ss << "[Validation]";
|
||||||
|
|
||||||
|
|
||||||
ss << "[" << pCallbackData->messageIdNumber << ":" << pCallbackData->pMessageIdName << "]: " << pCallbackData->pMessage;
|
ss << "[" << pCallbackData->messageIdNumber;
|
||||||
|
if (pCallbackData->pMessageIdName)
|
||||||
|
ss << ":" << pCallbackData->pMessageIdName;
|
||||||
|
|
||||||
|
ss << "]: " << pCallbackData->pMessage;
|
||||||
|
|
||||||
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
if (messageSeverity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT)
|
||||||
NazaraError(ss.str());
|
NazaraError(ss.str());
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,163 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_BINOP_HPP
|
||||||
|
#define NAZARA_SHADERNODES_BINOP_HPP
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
class BinOp : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BinOp(ShaderGraph& graph);
|
||||||
|
~BinOp() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
|
virtual QString GetOperationString() const = 0;
|
||||||
|
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) = 0;
|
||||||
|
|
||||||
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
void UpdateOutput();
|
||||||
|
|
||||||
|
std::shared_ptr<DataType> m_lhs;
|
||||||
|
std::shared_ptr<DataType> m_rhs;
|
||||||
|
std::shared_ptr<DataType> m_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class BinAdd : public BinOp<DataType, Nz::ShaderNodes::BinaryType::Add>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinOp<DataType, Nz::ShaderNodes::BinaryType::Add>::BinOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class BinMul : public BinOp<DataType, Nz::ShaderNodes::BinaryType::Multiply>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinOp<DataType, Nz::ShaderNodes::BinaryType::Multiply>::BinOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class BinSub : public BinOp<DataType, Nz::ShaderNodes::BinaryType::Substract>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinOp<DataType, Nz::ShaderNodes::BinaryType::Substract>::BinOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class BinDiv : public BinOp<DataType, Nz::ShaderNodes::BinaryType::Divide>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinOp<DataType, Nz::ShaderNodes::BinaryType::Divide>::BinOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FloatAdd : public BinAdd<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinAdd<FloatData>::BinAdd;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float addition"; }
|
||||||
|
QString name() const override { return "float_add"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatMul : public BinMul<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinMul<FloatData>::BinMul;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float multiplication"; }
|
||||||
|
QString name() const override { return "float_mul"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatSub : public BinMul<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinMul<FloatData>::BinMul;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float subtraction"; }
|
||||||
|
QString name() const override { return "float_sub"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatDiv : public BinDiv<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinDiv<FloatData>::BinDiv;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float division"; }
|
||||||
|
QString name() const override { return "float_div"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VecAdd : public BinAdd<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinAdd<VecData>::BinAdd;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector addition"; }
|
||||||
|
QString name() const override { return "vec_add"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecMul : public BinMul<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinMul<VecData>::BinMul;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector multiplication"; }
|
||||||
|
QString name() const override { return "vec_mul"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecSub : public BinMul<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinMul<VecData>::BinMul;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector subtraction"; }
|
||||||
|
QString name() const override { return "vec_sub"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecDiv : public BinDiv<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using BinDiv<VecData>::BinDiv;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector division"; }
|
||||||
|
QString name() const override { return "vec_div"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/BinOp.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,240 @@
|
||||||
|
#include <ShaderNode/DataModels/BinOp.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
BinOp<DataType, Op>::BinOp(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
Nz::ShaderNodes::NodePtr BinOp<DataType, Op>::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<Op>;
|
||||||
|
constexpr BuilderType builder;
|
||||||
|
return builder(expressions[0], expressions[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QtNodes::NodeDataType BinOp<DataType, Op>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
|
||||||
|
return DataType::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
unsigned int BinOp<DataType, Op>::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return 2;
|
||||||
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
std::shared_ptr<QtNodes::NodeData> BinOp<DataType, Op>::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
assert(port == 0);
|
||||||
|
return m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QString BinOp<DataType, Op>::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
switch (portIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "A";
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return "B";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return "A " + GetOperationString() + " B";
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
bool BinOp<DataType, Op>::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
return portType == QtNodes::PortType::In || portType == QtNodes::PortType::Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
void BinOp<DataType, Op>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
{
|
||||||
|
assert(index == 0 || index == 1);
|
||||||
|
|
||||||
|
std::shared_ptr<DataType> castedValue;
|
||||||
|
if (value && value->type().id == DataType::Type().id)
|
||||||
|
castedValue = std::static_pointer_cast<DataType>(value);
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
m_lhs = std::move(castedValue);
|
||||||
|
else
|
||||||
|
m_rhs = std::move(castedValue);
|
||||||
|
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QtNodes::NodeValidationState BinOp<DataType, Op>::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
{
|
||||||
|
if (m_lhs->componentCount != m_rhs->componentCount)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QString BinOp<DataType, Op>::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return "Missing operands";
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
{
|
||||||
|
if (m_lhs->componentCount != m_rhs->componentCount)
|
||||||
|
return "Incompatible components count (left has " + QString::number(m_lhs->componentCount) + ", right has " + QString::number(m_rhs->componentCount) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
bool BinOp<DataType, Op>::ComputePreview(QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
void BinOp<DataType, Op>::UpdateOutput()
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
{
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
m_output = std::make_shared<DataType>(4);
|
||||||
|
else
|
||||||
|
m_output = std::make_shared<DataType>();
|
||||||
|
|
||||||
|
m_output->preview = PreviewValues(1, 1);
|
||||||
|
m_output->preview.Fill(Nz::Vector4f::Zero());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
m_output = std::make_shared<DataType>(m_lhs->componentCount);
|
||||||
|
else
|
||||||
|
m_output = std::make_shared<DataType>();
|
||||||
|
|
||||||
|
const PreviewValues& leftPreview = m_lhs->preview;
|
||||||
|
const PreviewValues& rightPreview = m_rhs->preview;
|
||||||
|
std::size_t maxWidth = std::max(leftPreview.GetWidth(), rightPreview.GetWidth());
|
||||||
|
std::size_t maxHeight = std::max(leftPreview.GetHeight(), rightPreview.GetHeight());
|
||||||
|
|
||||||
|
// FIXME: Prevent useless copy
|
||||||
|
PreviewValues leftResized = leftPreview;
|
||||||
|
if (leftResized.GetWidth() != maxWidth || leftResized.GetHeight() != maxHeight)
|
||||||
|
leftResized = leftResized.Resized(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
PreviewValues rightResized = rightPreview;
|
||||||
|
if (rightResized.GetWidth() != maxWidth || rightResized.GetHeight() != maxHeight)
|
||||||
|
rightResized = rightResized.Resized(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
m_output->preview = PreviewValues(maxWidth, maxHeight);
|
||||||
|
ApplyOp(leftResized.GetData(), rightResized.GetData(), m_output->preview.GetData(), maxWidth * maxHeight);
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void BinAdd<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
output[i] = left[i] + right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString BinAdd<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "+";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void BinMul<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
output[i] = left[i] * right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString BinMul<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "*";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void BinSub<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
output[i] = left[i] - right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString BinSub<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "-";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void BinDiv<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
output[i] = left[i] / right[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString BinDiv<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "/";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
#include <ShaderNode/DataModels/BoolValue.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/BoolData.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
#include <QtWidgets/QCheckBox>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
BoolValue::BoolValue(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph),
|
||||||
|
m_value(true)
|
||||||
|
{
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BoolValue::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Boolean constant";
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BoolValue::name() const
|
||||||
|
{
|
||||||
|
static QString name = "bool_constant";
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeDataType BoolValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
return BoolData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int BoolValue::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return 0;
|
||||||
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> BoolValue::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
assert(port == 0);
|
||||||
|
|
||||||
|
float c = (m_value) ? 1.f : 0.f;
|
||||||
|
|
||||||
|
auto out = std::make_shared<BoolData>();
|
||||||
|
out->preview(0, 0) = Nz::Vector4f(c, c, c, 1.f);
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString BoolValue::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
|
||||||
|
return (m_value) ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoolValue::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return portType == QtNodes::PortType::Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoolValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
|
{
|
||||||
|
ShaderNode::BuildNodeEdition(layout);
|
||||||
|
|
||||||
|
QCheckBox* checkbox = new QCheckBox;
|
||||||
|
checkbox->setCheckState((m_value) ? Qt::Checked : Qt::Unchecked);
|
||||||
|
connect(checkbox, &QCheckBox::stateChanged, [=](int newState)
|
||||||
|
{
|
||||||
|
m_value = (newState == Qt::Checked);
|
||||||
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
});
|
||||||
|
|
||||||
|
layout->addRow(tr("Value"), checkbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BoolValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
return Nz::ShaderBuilder::Constant(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoolValue::ComputePreview(QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
pixmap.fill(ToColor());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor BoolValue::ToColor() const
|
||||||
|
{
|
||||||
|
float value = (m_value) ? 1.f : 0.f;
|
||||||
|
|
||||||
|
return QColor::fromRgbF(value, value, value, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoolValue::restore(const QJsonObject& data)
|
||||||
|
{
|
||||||
|
m_value = float(data["value"].toBool(m_value));
|
||||||
|
|
||||||
|
ShaderNode::restore(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
QJsonObject BoolValue::save() const
|
||||||
|
{
|
||||||
|
QJsonObject data = ShaderNode::save();
|
||||||
|
data["value"] = m_value;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_BOOLVALUE_HPP
|
||||||
|
#define NAZARA_SHADERNODES_BOOLVALUE_HPP
|
||||||
|
|
||||||
|
#include <QtGui/QImage>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QFormLayout>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
class BoolValue : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BoolValue(ShaderGraph& graph);
|
||||||
|
~BoolValue() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
|
QString caption() const override;
|
||||||
|
QString name() const override;
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
QColor ToColor() const;
|
||||||
|
|
||||||
|
void restore(const QJsonObject& data) override;
|
||||||
|
QJsonObject save() const override;
|
||||||
|
|
||||||
|
bool m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/BoolValue.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
#include <ShaderNode/DataModels/BoolValue.hpp>
|
||||||
|
|
@ -49,9 +49,10 @@ ShaderNode(graph)
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr BufferField::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderNodes::NodePtr BufferField::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
if (!m_currentBufferIndex)
|
if (!m_currentBufferIndex)
|
||||||
throw std::runtime_error("no buffer");
|
throw std::runtime_error("no buffer");
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,9 @@ class BufferField : public ShaderNode
|
||||||
BufferField(ShaderGraph& graph);
|
BufferField(ShaderGraph& graph);
|
||||||
~BufferField() = default;
|
~BufferField() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const override;
|
|
||||||
|
|
||||||
QString caption() const override { return "BufferField"; }
|
QString caption() const override { return "BufferField"; }
|
||||||
QString name() const override { return "BufferField"; }
|
QString name() const override { return "BufferField"; }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,9 @@ class CastVec : public ShaderNode
|
||||||
CastVec(ShaderGraph& graph);
|
CastVec(ShaderGraph& graph);
|
||||||
~CastVec() = default;
|
~CastVec() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const;
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,44 @@ ShaderNode(graph)
|
||||||
m_output = std::make_shared<VecData>(ToComponentCount);
|
m_output = std::make_shared<VecData>(ToComponentCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<std::size_t ToComponentCount>
|
||||||
|
Nz::ShaderNodes::NodePtr CastVec<ToComponentCount>::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(m_input);
|
||||||
|
assert(count == 1);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
std::size_t fromComponentCount = m_input->componentCount;
|
||||||
|
|
||||||
|
if (ToComponentCount > fromComponentCount)
|
||||||
|
{
|
||||||
|
std::size_t overflowComponentCount = ToComponentCount - fromComponentCount;
|
||||||
|
|
||||||
|
std::array<Nz::ShaderNodes::ExpressionPtr, 4> expr;
|
||||||
|
expr[0] = expressions[0];
|
||||||
|
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
||||||
|
expr[i + 1] = Nz::ShaderBuilder::Constant(m_overflowComponents[i]);
|
||||||
|
|
||||||
|
constexpr auto ExpressionType = VecExpressionType<ToComponentCount>;
|
||||||
|
|
||||||
|
return Nz::ShaderBuilder::Cast<ExpressionType>(expr.data(), 1 + overflowComponentCount);
|
||||||
|
}
|
||||||
|
else if (ToComponentCount < fromComponentCount)
|
||||||
|
{
|
||||||
|
std::array<Nz::ShaderNodes::SwizzleComponent, ToComponentCount> swizzleComponents;
|
||||||
|
for (std::size_t i = 0; i < ToComponentCount; ++i)
|
||||||
|
swizzleComponents[i] = static_cast<Nz::ShaderNodes::SwizzleComponent>(static_cast<std::size_t>(Nz::ShaderNodes::SwizzleComponent::First) + i);
|
||||||
|
|
||||||
|
return std::apply([&](auto... components)
|
||||||
|
{
|
||||||
|
std::initializer_list<Nz::ShaderNodes::SwizzleComponent> componentList{ components... };
|
||||||
|
return Nz::ShaderBuilder::Swizzle(expressions[0], componentList);
|
||||||
|
}, swizzleComponents);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return expressions[0]; //< no-op
|
||||||
|
}
|
||||||
|
|
||||||
template<std::size_t ToComponentCount>
|
template<std::size_t ToComponentCount>
|
||||||
void CastVec<ToComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
void CastVec<ToComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
{
|
{
|
||||||
|
|
@ -48,43 +86,6 @@ void CastVec<ToComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t ToComponentCount>
|
|
||||||
Nz::ShaderNodes::ExpressionPtr CastVec<ToComponentCount>::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
|
||||||
{
|
|
||||||
assert(m_input);
|
|
||||||
assert(count == 1);
|
|
||||||
|
|
||||||
std::size_t fromComponentCount = m_input->componentCount;
|
|
||||||
|
|
||||||
if (ToComponentCount > fromComponentCount)
|
|
||||||
{
|
|
||||||
std::size_t overflowComponentCount = ToComponentCount - fromComponentCount;
|
|
||||||
|
|
||||||
std::array<Nz::ShaderNodes::ExpressionPtr, 4> expr;
|
|
||||||
expr[0] = expressions[0];
|
|
||||||
for (std::size_t i = 0; i < overflowComponentCount; ++i)
|
|
||||||
expr[i + 1] = Nz::ShaderBuilder::Constant(m_overflowComponents[i]);
|
|
||||||
|
|
||||||
constexpr auto ExpressionType = VecExpressionType<ToComponentCount>;
|
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Cast<ExpressionType>(expr.data(), 1 + overflowComponentCount);
|
|
||||||
}
|
|
||||||
else if (ToComponentCount < fromComponentCount)
|
|
||||||
{
|
|
||||||
std::array<Nz::ShaderNodes::SwizzleComponent, ToComponentCount> swizzleComponents;
|
|
||||||
for (std::size_t i = 0; i < ToComponentCount; ++i)
|
|
||||||
swizzleComponents[i] = static_cast<Nz::ShaderNodes::SwizzleComponent>(static_cast<std::size_t>(Nz::ShaderNodes::SwizzleComponent::First) + i);
|
|
||||||
|
|
||||||
return std::apply([&](auto... components)
|
|
||||||
{
|
|
||||||
std::initializer_list<Nz::ShaderNodes::SwizzleComponent> componentList{ components... };
|
|
||||||
return Nz::ShaderBuilder::Swizzle(expressions[0], componentList);
|
|
||||||
}, swizzleComponents);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return expressions[0]; //< no-op
|
|
||||||
}
|
|
||||||
|
|
||||||
template<std::size_t ToComponentCount>
|
template<std::size_t ToComponentCount>
|
||||||
QString CastVec<ToComponentCount>::caption() const
|
QString CastVec<ToComponentCount>::caption() const
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,220 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_COMPOP_HPP
|
||||||
|
#define NAZARA_SHADERNODES_COMPOP_HPP
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/BoolData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
class CompOp : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CompOp(ShaderGraph& graph);
|
||||||
|
~CompOp() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
|
virtual QString GetOperationString() const = 0;
|
||||||
|
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
virtual void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) = 0;
|
||||||
|
|
||||||
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
void UpdateOutput();
|
||||||
|
|
||||||
|
std::shared_ptr<BoolData> m_output;
|
||||||
|
std::shared_ptr<DataType> m_lhs;
|
||||||
|
std::shared_ptr<DataType> m_rhs;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompEq : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompEq>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompEq>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompGe : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompGe>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompGe>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompGt : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompGt>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompGt>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompLe : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompLe>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompLe>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompLt : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompLt>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompLt>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
class CompNe : public CompOp<DataType, Nz::ShaderNodes::BinaryType::CompNe>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompOp<DataType, Nz::ShaderNodes::BinaryType::CompNe>::CompOp;
|
||||||
|
|
||||||
|
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
||||||
|
QString GetOperationString() const final;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class FloatEq : public CompEq<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompEq<FloatData>::CompEq;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float equality"; }
|
||||||
|
QString name() const override { return "float_eq"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatGe : public CompGe<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompGe<FloatData>::CompGe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float greater than or equal"; }
|
||||||
|
QString name() const override { return "float_ge"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatGt : public CompGt<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompGt<FloatData>::CompGt;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float greater than"; }
|
||||||
|
QString name() const override { return "float_gt"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatLe : public CompLe<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompLe<FloatData>::CompLe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float less than or equal"; }
|
||||||
|
QString name() const override { return "float_le"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatLt : public CompLt<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompLt<FloatData>::CompLt;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float less than"; }
|
||||||
|
QString name() const override { return "float_lt"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FloatNe : public CompNe<FloatData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompNe<FloatData>::CompNe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Float inequality"; }
|
||||||
|
QString name() const override { return "float_ne"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class VecEq : public CompEq<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompEq<VecData>::CompEq;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector equality"; }
|
||||||
|
QString name() const override { return "vec_eq"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecGe : public CompGe<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompGe<VecData>::CompGe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector greater than or equal"; }
|
||||||
|
QString name() const override { return "vec_ge"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecGt : public CompGt<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompGt<VecData>::CompGt;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector greater than"; }
|
||||||
|
QString name() const override { return "vec_gt"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecLe : public CompLe<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompLe<VecData>::CompLe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector less than or equal"; }
|
||||||
|
QString name() const override { return "vec_le"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecLt : public CompLt<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompLt<VecData>::CompLt;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector less than"; }
|
||||||
|
QString name() const override { return "vec_lt"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class VecNe : public CompNe<VecData>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using CompNe<VecData>::CompNe;
|
||||||
|
|
||||||
|
QString caption() const override { return "Vector inequality"; }
|
||||||
|
QString name() const override { return "vec_ne"; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/CompOp.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
#include <ShaderNode/DataModels/CompOp.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
CompOp<DataType, Op>::CompOp(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
Nz::ShaderNodes::NodePtr CompOp<DataType, Op>::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<Op>;
|
||||||
|
constexpr BuilderType builder;
|
||||||
|
return builder(expressions[0], expressions[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QtNodes::NodeDataType CompOp<DataType, Op>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
return DataType::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return BoolData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
unsigned int CompOp<DataType, Op>::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return 2;
|
||||||
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
std::shared_ptr<QtNodes::NodeData> CompOp<DataType, Op>::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
assert(port == 0);
|
||||||
|
return m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QString CompOp<DataType, Op>::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
switch (portIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return "A";
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return "B";
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return "A " + GetOperationString() + " B";
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString{};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
bool CompOp<DataType, Op>::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
return portType == QtNodes::PortType::In || portType == QtNodes::PortType::Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
void CompOp<DataType, Op>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
{
|
||||||
|
assert(index == 0 || index == 1);
|
||||||
|
|
||||||
|
std::shared_ptr<DataType> castedValue;
|
||||||
|
if (value && value->type().id == DataType::Type().id)
|
||||||
|
castedValue = std::static_pointer_cast<DataType>(value);
|
||||||
|
|
||||||
|
if (index == 0)
|
||||||
|
m_lhs = std::move(castedValue);
|
||||||
|
else
|
||||||
|
m_rhs = std::move(castedValue);
|
||||||
|
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QtNodes::NodeValidationState CompOp<DataType, Op>::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
{
|
||||||
|
if (m_lhs->componentCount != m_rhs->componentCount)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
QString CompOp<DataType, Op>::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return "Missing operands";
|
||||||
|
|
||||||
|
if constexpr (std::is_same_v<DataType, VecData>)
|
||||||
|
{
|
||||||
|
if (m_lhs->componentCount != m_rhs->componentCount)
|
||||||
|
return "Incompatible components count (left has " + QString::number(m_lhs->componentCount) + ", right has " + QString::number(m_rhs->componentCount) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
bool CompOp<DataType, Op>::ComputePreview(QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
if (!m_lhs || !m_rhs)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType, Nz::ShaderNodes::BinaryType Op>
|
||||||
|
void CompOp<DataType, Op>::UpdateOutput()
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
{
|
||||||
|
m_output = std::make_shared<BoolData>();
|
||||||
|
m_output->preview = PreviewValues(1, 1);
|
||||||
|
m_output->preview.Fill(Nz::Vector4f::Zero());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_output = std::make_shared<BoolData>();
|
||||||
|
|
||||||
|
const PreviewValues& leftPreview = m_lhs->preview;
|
||||||
|
const PreviewValues& rightPreview = m_rhs->preview;
|
||||||
|
std::size_t maxWidth = std::max(leftPreview.GetWidth(), rightPreview.GetWidth());
|
||||||
|
std::size_t maxHeight = std::max(leftPreview.GetHeight(), rightPreview.GetHeight());
|
||||||
|
|
||||||
|
// FIXME: Prevent useless copy
|
||||||
|
PreviewValues leftResized = leftPreview;
|
||||||
|
if (leftResized.GetWidth() != maxWidth || leftResized.GetHeight() != maxHeight)
|
||||||
|
leftResized = leftResized.Resized(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
PreviewValues rightResized = rightPreview;
|
||||||
|
if (rightResized.GetWidth() != maxWidth || rightResized.GetHeight() != maxHeight)
|
||||||
|
rightResized = rightResized.Resized(maxWidth, maxHeight);
|
||||||
|
|
||||||
|
m_output->preview = PreviewValues(maxWidth, maxHeight);
|
||||||
|
ApplyOp(leftResized.GetData(), rightResized.GetData(), m_output->preview.GetData(), maxWidth * maxHeight);
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompEq<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] == right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompEq<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "==";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompGe<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] >= right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompGe<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return ">=";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompGt<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] > right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompGt<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompLe<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] >= right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompLe<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "<=";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompLt<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] > right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompLt<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "<";
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
void CompNe<DataType>::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < pixelCount; ++i)
|
||||||
|
{
|
||||||
|
float r = (left[i] != right[i]) ? 1.f : 0.f;
|
||||||
|
output[i] = Nz::Vector4f(r, r, r, r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename DataType>
|
||||||
|
QString CompNe<DataType>::GetOperationString() const
|
||||||
|
{
|
||||||
|
return "!=";
|
||||||
|
}
|
||||||
|
|
@ -35,9 +35,10 @@ ShaderNode(graph)
|
||||||
UpdatePreview();
|
UpdatePreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr ConditionalExpression::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr ConditionalExpression::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
if (!m_currentConditionIndex)
|
if (!m_currentConditionIndex)
|
||||||
throw std::runtime_error("no condition");
|
throw std::runtime_error("no condition");
|
||||||
|
|
@ -100,15 +101,48 @@ void ConditionalExpression::BuildNodeEdition(QFormLayout* layout)
|
||||||
|
|
||||||
auto ConditionalExpression::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType
|
auto ConditionalExpression::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const -> QtNodes::NodeDataType
|
||||||
{
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
switch (portIndex)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
if (!m_truePath && !m_falsePath)
|
||||||
|
return VecData::Type();
|
||||||
|
|
||||||
|
return (m_truePath) ? m_truePath->type() : m_falsePath->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
if (!m_truePath && !m_falsePath)
|
||||||
|
return VecData::Type();
|
||||||
|
|
||||||
|
return (m_falsePath) ? m_falsePath->type() : m_truePath->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
if (!m_truePath && !m_falsePath)
|
||||||
|
return VecData::Type();
|
||||||
|
|
||||||
|
return (m_truePath) ? m_truePath->type() : m_falsePath->type();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
return VecData::Type();
|
return VecData::Type();
|
||||||
|
|
||||||
assert(portType == QtNodes::PortType::Out);
|
|
||||||
assert(portIndex == 0);
|
|
||||||
|
|
||||||
if (!m_truePath && !m_falsePath)
|
|
||||||
return VecData::Type();
|
|
||||||
|
|
||||||
return (m_truePath) ? m_truePath->type() : m_falsePath->type();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ConditionalExpression::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
QString ConditionalExpression::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
|
@ -120,10 +154,10 @@ QString ConditionalExpression::portCaption(QtNodes::PortType portType, QtNodes::
|
||||||
switch (portIndex)
|
switch (portIndex)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
return "True path";
|
return "True expression";
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return "False path";
|
return "False expression";
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -189,6 +223,9 @@ QtNodes::NodeValidationState ConditionalExpression::validationState() const
|
||||||
|
|
||||||
QString ConditionalExpression::validationMessage() const
|
QString ConditionalExpression::validationMessage() const
|
||||||
{
|
{
|
||||||
|
if (!m_currentConditionIndex)
|
||||||
|
return "Invalid condition";
|
||||||
|
|
||||||
if (!m_truePath || !m_falsePath)
|
if (!m_truePath || !m_falsePath)
|
||||||
return "Missing input";
|
return "Missing input";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,9 @@ class ConditionalExpression : public ShaderNode
|
||||||
ConditionalExpression(ShaderGraph& graph);
|
ConditionalExpression(ShaderGraph& graph);
|
||||||
~ConditionalExpression() = default;
|
~ConditionalExpression() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const override;
|
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,9 +36,13 @@ unsigned int FloatValue::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
case QtNodes::PortType::In: return 0;
|
case QtNodes::PortType::In: return 0;
|
||||||
case QtNodes::PortType::Out: return 1;
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> FloatValue::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> FloatValue::outData(QtNodes::PortIndex port)
|
||||||
|
|
@ -51,6 +55,20 @@ std::shared_ptr<QtNodes::NodeData> FloatValue::outData(QtNodes::PortIndex port)
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString FloatValue::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
|
||||||
|
return QString::number(m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FloatValue::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return portType == QtNodes::PortType::Out;
|
||||||
|
}
|
||||||
|
|
||||||
void FloatValue::BuildNodeEdition(QFormLayout* layout)
|
void FloatValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
{
|
{
|
||||||
ShaderNode::BuildNodeEdition(layout);
|
ShaderNode::BuildNodeEdition(layout);
|
||||||
|
|
@ -71,9 +89,10 @@ void FloatValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
layout->addRow(tr("Value"), spinbox);
|
layout->addRow(tr("Value"), spinbox);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr FloatValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderNodes::NodePtr FloatValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Constant(m_value);
|
return Nz::ShaderBuilder::Constant(m_value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,9 @@ class FloatValue : public ShaderNode
|
||||||
FloatValue(ShaderGraph& graph);
|
FloatValue(ShaderGraph& graph);
|
||||||
~FloatValue() = default;
|
~FloatValue() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
|
|
@ -26,9 +29,8 @@ class FloatValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
|
|
||||||
|
|
@ -109,9 +109,10 @@ void InputValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
layout->addRow(tr("Input"), inputSelection);
|
layout->addRow(tr("Input"), inputSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr InputValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderNodes::NodePtr InputValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
if (!m_currentInputIndex)
|
if (!m_currentInputIndex)
|
||||||
throw std::runtime_error("no input");
|
throw std::runtime_error("no input");
|
||||||
|
|
@ -184,6 +185,35 @@ std::shared_ptr<QtNodes::NodeData> InputValue::outData(QtNodes::PortIndex port)
|
||||||
throw std::runtime_error("Unhandled input type");
|
throw std::runtime_error("Unhandled input type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString InputValue::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
|
||||||
|
if (!m_currentInputIndex)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
const auto& inputEntry = GetGraph().GetInput(*m_currentInputIndex);
|
||||||
|
return QString::fromStdString(inputEntry.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputValue::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return false;
|
||||||
|
case QtNodes::PortType::Out: return m_currentInputIndex.has_value();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
QtNodes::NodeValidationState InputValue::validationState() const
|
QtNodes::NodeValidationState InputValue::validationState() const
|
||||||
{
|
{
|
||||||
if (!m_currentInputIndex)
|
if (!m_currentInputIndex)
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ class InputValue : public ShaderNode
|
||||||
|
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override { return "Input"; }
|
QString caption() const override { return "Input"; }
|
||||||
QString name() const override { return "Input"; }
|
QString name() const override { return "Input"; }
|
||||||
|
|
@ -30,6 +30,9 @@ class InputValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
QtNodes::NodeValidationState validationState() const override;
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
QString validationMessage() const override;
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,14 +6,14 @@
|
||||||
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
|
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
class Mat4BinOp : public ShaderNode
|
class Mat4BinOp : public ShaderNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Mat4BinOp(ShaderGraph& graph);
|
Mat4BinOp(ShaderGraph& graph);
|
||||||
~Mat4BinOp() = default;
|
~Mat4BinOp() = default;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const;
|
||||||
|
|
||||||
unsigned int nPorts(QtNodes::PortType portType) const override;
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,51 +1,55 @@
|
||||||
#include <ShaderNode/DataModels/Mat4BinOp.hpp>
|
#include <ShaderNode/DataModels/Mat4BinOp.hpp>
|
||||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
Mat4BinOp<BinOp>::Mat4BinOp(ShaderGraph& graph) :
|
Mat4BinOp<Op>::Mat4BinOp(ShaderGraph& graph) :
|
||||||
ShaderNode(graph)
|
ShaderNode(graph)
|
||||||
{
|
{
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
Nz::ShaderNodes::ExpressionPtr Mat4BinOp<BinOp>::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr Mat4BinOp<Op>::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<Op>;
|
||||||
constexpr BuilderType builder;
|
constexpr BuilderType builder;
|
||||||
return builder(expressions[0], expressions[1]);
|
return builder(expressions[0], expressions[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
QtNodes::NodeDataType Mat4BinOp<BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
QtNodes::NodeDataType Mat4BinOp<Op>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
assert(portIndex == 0 || portIndex == 1);
|
assert(portIndex == 0 || portIndex == 1);
|
||||||
|
|
||||||
return Matrix4Data::Type();
|
return Matrix4Data::Type();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
unsigned int Mat4BinOp<BinOp>::nPorts(QtNodes::PortType portType) const
|
unsigned int Mat4BinOp<Op>::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
switch (portType)
|
switch (portType)
|
||||||
{
|
{
|
||||||
case QtNodes::PortType::In: return 2;
|
case QtNodes::PortType::In: return 2;
|
||||||
case QtNodes::PortType::Out: return 1;
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid port type");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
std::shared_ptr<QtNodes::NodeData> Mat4BinOp<BinOp>::outData(QtNodes::PortIndex port)
|
std::shared_ptr<QtNodes::NodeData> Mat4BinOp<Op>::outData(QtNodes::PortIndex port)
|
||||||
{
|
{
|
||||||
assert(port == 0);
|
assert(port == 0);
|
||||||
return m_output;
|
return m_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
void Mat4BinOp<BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
void Mat4BinOp<Op>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
{
|
{
|
||||||
assert(index == 0 || index == 1);
|
assert(index == 0 || index == 1);
|
||||||
|
|
||||||
|
|
@ -64,8 +68,8 @@ void Mat4BinOp<BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int i
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
QtNodes::NodeValidationState Mat4BinOp<BinOp>::validationState() const
|
QtNodes::NodeValidationState Mat4BinOp<Op>::validationState() const
|
||||||
{
|
{
|
||||||
if (!m_lhs || !m_rhs)
|
if (!m_lhs || !m_rhs)
|
||||||
return QtNodes::NodeValidationState::Error;
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
@ -73,8 +77,8 @@ QtNodes::NodeValidationState Mat4BinOp<BinOp>::validationState() const
|
||||||
return QtNodes::NodeValidationState::Valid;
|
return QtNodes::NodeValidationState::Valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
QString Mat4BinOp<BinOp>::validationMessage() const
|
QString Mat4BinOp<Op>::validationMessage() const
|
||||||
{
|
{
|
||||||
if (!m_lhs || !m_rhs)
|
if (!m_lhs || !m_rhs)
|
||||||
return "Missing operands";
|
return "Missing operands";
|
||||||
|
|
@ -82,8 +86,8 @@ QString Mat4BinOp<BinOp>::validationMessage() const
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
bool Mat4BinOp<BinOp>::ComputePreview(QPixmap& pixmap)
|
bool Mat4BinOp<Op>::ComputePreview(QPixmap& pixmap)
|
||||||
{
|
{
|
||||||
if (!m_lhs || !m_rhs)
|
if (!m_lhs || !m_rhs)
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -94,8 +98,8 @@ bool Mat4BinOp<BinOp>::ComputePreview(QPixmap& pixmap)
|
||||||
//return true;
|
//return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
template<Nz::ShaderNodes::BinaryType Op>
|
||||||
void Mat4BinOp<BinOp>::UpdateOutput()
|
void Mat4BinOp<Op>::UpdateOutput()
|
||||||
{
|
{
|
||||||
if (validationState() != QtNodes::NodeValidationState::Valid)
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ ShaderNode(graph)
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr Mat4VecMul::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr Mat4VecMul::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
using namespace Nz::ShaderNodes;
|
using namespace Nz::ShaderNodes;
|
||||||
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
|
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class Mat4VecMul : public ShaderNode
|
||||||
Mat4VecMul(ShaderGraph& graph);
|
Mat4VecMul(ShaderGraph& graph);
|
||||||
~Mat4VecMul() = default;
|
~Mat4VecMul() = default;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,13 @@ void OutputValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
layout->addRow(tr("Output"), outputSelection);
|
layout->addRow(tr("Output"), outputSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr OutputValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr OutputValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
using namespace Nz::ShaderBuilder;
|
using namespace Nz::ShaderBuilder;
|
||||||
using namespace Nz::ShaderNodes;
|
using namespace Nz::ShaderNodes;
|
||||||
|
|
||||||
assert(count == 1);
|
assert(count == 1);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
if (!m_currentOutputIndex)
|
if (!m_currentOutputIndex)
|
||||||
throw std::runtime_error("no output");
|
throw std::runtime_error("no output");
|
||||||
|
|
@ -70,6 +71,11 @@ Nz::ShaderNodes::ExpressionPtr OutputValue::GetExpression(Nz::ShaderNodes::Expre
|
||||||
return Nz::ShaderBuilder::Assign(std::move(output), *expressions);
|
return Nz::ShaderBuilder::Assign(std::move(output), *expressions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> OutputValue::outData(QtNodes::PortIndex /*port*/)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
QtNodes::NodeDataType OutputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
QtNodes::NodeDataType OutputValue::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
assert(portType == QtNodes::PortType::In);
|
assert(portType == QtNodes::PortType::In);
|
||||||
|
|
@ -88,14 +94,40 @@ unsigned int OutputValue::nPorts(QtNodes::PortType portType) const
|
||||||
{
|
{
|
||||||
case QtNodes::PortType::In: return 1;
|
case QtNodes::PortType::In: return 1;
|
||||||
case QtNodes::PortType::Out: return 0;
|
case QtNodes::PortType::Out: return 0;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
assert(false);
|
||||||
|
throw std::runtime_error("invalid port type");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> OutputValue::outData(QtNodes::PortIndex /*port*/)
|
QString OutputValue::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
{
|
{
|
||||||
return {};
|
assert(portType == QtNodes::PortType::In);
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
if (!m_currentOutputIndex)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
const auto& outputEntry = GetGraph().GetOutput(*m_currentOutputIndex);
|
||||||
|
return QString::fromStdString(outputEntry.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OutputValue::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return m_currentOutputIndex.has_value();
|
||||||
|
case QtNodes::PortType::Out: return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutputValue::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
void OutputValue::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ class OutputValue : public ShaderNode
|
||||||
|
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override { return "Output"; }
|
QString caption() const override { return "Output"; }
|
||||||
QString name() const override { return "Output"; }
|
QString name() const override { return "Output"; }
|
||||||
|
|
@ -27,6 +27,9 @@ class OutputValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
QtNodes::NodeValidationState validationState() const override;
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@ ShaderNode(graph)
|
||||||
DisableCustomVariableName();
|
DisableCustomVariableName();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr PositionOutputValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr PositionOutputValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
using namespace Nz::ShaderBuilder;
|
using namespace Nz::ShaderBuilder;
|
||||||
using namespace Nz::ShaderNodes;
|
using namespace Nz::ShaderNodes;
|
||||||
|
|
||||||
assert(count == 1);
|
assert(count == 1);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
auto output = Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Builtin(BuiltinEntry::VertexPosition));
|
auto output = Nz::ShaderBuilder::Identifier(Nz::ShaderBuilder::Builtin(BuiltinEntry::VertexPosition));
|
||||||
return Nz::ShaderBuilder::Assign(std::move(output), *expressions);
|
return Nz::ShaderBuilder::Assign(std::move(output), *expressions);
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ class PositionOutputValue : public ShaderNode
|
||||||
public:
|
public:
|
||||||
PositionOutputValue(ShaderGraph& graph);
|
PositionOutputValue(ShaderGraph& graph);
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override { return "PositionOutputValue"; }
|
QString caption() const override { return "PositionOutputValue"; }
|
||||||
QString name() const override { return "PositionOutputValue"; }
|
QString name() const override { return "PositionOutputValue"; }
|
||||||
|
|
|
||||||
|
|
@ -71,11 +71,12 @@ bool SampleTexture::ComputePreview(QPixmap& pixmap)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr SampleTexture::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr SampleTexture::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(m_texture);
|
assert(m_texture);
|
||||||
assert(m_uv);
|
assert(m_uv);
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Sample2D(expressions[0], expressions[1]);
|
return Nz::ShaderBuilder::Sample2D(expressions[0], expressions[1]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class SampleTexture : public ShaderNode
|
||||||
SampleTexture(ShaderGraph& graph);
|
SampleTexture(ShaderGraph& graph);
|
||||||
~SampleTexture() = default;
|
~SampleTexture() = default;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override { return "Sample texture"; }
|
QString caption() const override { return "Sample texture"; }
|
||||||
QString name() const override { return "SampleTexture"; }
|
QString name() const override { return "SampleTexture"; }
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,11 @@ void ShaderNode::EnablePreview(bool enable)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ShaderNode::GetOutputOrder() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QWidget* ShaderNode::embeddedWidget()
|
QWidget* ShaderNode::embeddedWidget()
|
||||||
{
|
{
|
||||||
if (!m_embeddedWidget)
|
if (!m_embeddedWidget)
|
||||||
|
|
|
||||||
|
|
@ -18,14 +18,15 @@ class ShaderNode : public QtNodes::NodeDataModel
|
||||||
public:
|
public:
|
||||||
ShaderNode(ShaderGraph& graph);
|
ShaderNode(ShaderGraph& graph);
|
||||||
|
|
||||||
|
virtual Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const = 0;
|
||||||
virtual void BuildNodeEdition(QFormLayout* layout);
|
virtual void BuildNodeEdition(QFormLayout* layout);
|
||||||
|
|
||||||
inline void DisablePreview();
|
inline void DisablePreview();
|
||||||
void EnablePreview(bool enable = true);
|
void EnablePreview(bool enable = true);
|
||||||
|
|
||||||
virtual Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const = 0;
|
|
||||||
inline ShaderGraph& GetGraph();
|
inline ShaderGraph& GetGraph();
|
||||||
inline const ShaderGraph& GetGraph() const;
|
inline const ShaderGraph& GetGraph() const;
|
||||||
|
virtual int GetOutputOrder() const;
|
||||||
inline const std::string& GetVariableName() const;
|
inline const std::string& GetVariableName() const;
|
||||||
|
|
||||||
inline void SetPreviewSize(const Nz::Vector2i& size);
|
inline void SetPreviewSize(const Nz::Vector2i& size);
|
||||||
|
|
|
||||||
|
|
@ -110,12 +110,13 @@ void TextureValue::BuildNodeEdition(QFormLayout* layout)
|
||||||
layout->addRow(tr("Texture"), textureSelection);
|
layout->addRow(tr("Texture"), textureSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr TextureValue::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderNodes::NodePtr TextureValue::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
if (!m_currentTextureIndex)
|
if (!m_currentTextureIndex)
|
||||||
throw std::runtime_error("invalid texture input");
|
throw std::runtime_error("invalid texture input");
|
||||||
|
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
const auto& textureEntry = GetGraph().GetTexture(*m_currentTextureIndex);
|
const auto& textureEntry = GetGraph().GetTexture(*m_currentTextureIndex);
|
||||||
|
|
||||||
|
|
@ -178,6 +179,32 @@ std::shared_ptr<QtNodes::NodeData> TextureValue::outData(QtNodes::PortIndex port
|
||||||
return textureData;
|
return textureData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString TextureValue::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
|
||||||
|
if (!m_currentTextureIndex)
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
const auto& textureEntry = GetGraph().GetTexture(*m_currentTextureIndex);
|
||||||
|
return QString::fromStdString(textureEntry.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TextureValue::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return false;
|
||||||
|
case QtNodes::PortType::Out: return m_currentTextureIndex.has_value();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
QtNodes::NodeValidationState TextureValue::validationState() const
|
QtNodes::NodeValidationState TextureValue::validationState() const
|
||||||
{
|
{
|
||||||
if (!m_currentTextureIndex)
|
if (!m_currentTextureIndex)
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ class TextureValue : public ShaderNode
|
||||||
|
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override { return "Texture"; }
|
QString caption() const override { return "Texture"; }
|
||||||
QString name() const override { return "Texture"; }
|
QString name() const override { return "Texture"; }
|
||||||
|
|
@ -29,6 +29,9 @@ class TextureValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
QtNodes::NodeValidationState validationState() const override;
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
QString validationMessage() const override;
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
|
||||||
|
|
||||||
QString VecAdd::caption() const
|
|
||||||
{
|
|
||||||
static QString caption = "Vector addition";
|
|
||||||
return caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VecAdd::name() const
|
|
||||||
{
|
|
||||||
static QString name = "vec_add";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VecAdd::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
|
||||||
output[i] = left[i] + right[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VecMul::caption() const
|
|
||||||
{
|
|
||||||
static QString caption = "Vector multiplication";
|
|
||||||
return caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VecMul::name() const
|
|
||||||
{
|
|
||||||
static QString name = "vec_mul";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VecMul::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
|
||||||
output[i] = left[i] * right[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VecSub::caption() const
|
|
||||||
{
|
|
||||||
static QString caption = "Vector subtraction";
|
|
||||||
return caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString VecSub::name() const
|
|
||||||
{
|
|
||||||
static QString name = "vec_sub";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VecSub::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
|
||||||
output[i] = left[i] - right[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
QString VecDiv::caption() const
|
|
||||||
{
|
|
||||||
static QString caption = "Vector divide";
|
|
||||||
return caption;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
QString VecDiv::name() const
|
|
||||||
{
|
|
||||||
static QString name = "vec_div";
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VecDiv::ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount)
|
|
||||||
{
|
|
||||||
for (std::size_t i = 0; i < pixelCount; ++i)
|
|
||||||
output[i] = left[i] / right[i];
|
|
||||||
}
|
|
||||||
|
|
@ -1,86 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#ifndef NAZARA_SHADERNODES_VECBINOP_HPP
|
|
||||||
#define NAZARA_SHADERNODES_VECBINOP_HPP
|
|
||||||
|
|
||||||
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
|
||||||
#include <ShaderNode/DataTypes/VecData.hpp>
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
class VecBinOp : public ShaderNode
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
VecBinOp(ShaderGraph& graph);
|
|
||||||
~VecBinOp() = default;
|
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
|
||||||
|
|
||||||
unsigned int nPorts(QtNodes::PortType portType) const override;
|
|
||||||
|
|
||||||
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
|
||||||
|
|
||||||
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
|
||||||
|
|
||||||
QtNodes::NodeValidationState validationState() const override;
|
|
||||||
QString validationMessage() const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
virtual void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) = 0;
|
|
||||||
|
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
|
||||||
void UpdateOutput();
|
|
||||||
|
|
||||||
std::shared_ptr<VecData> m_lhs;
|
|
||||||
std::shared_ptr<VecData> m_rhs;
|
|
||||||
std::shared_ptr<VecData> m_output;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VecAdd : public VecBinOp<Nz::ShaderNodes::BinaryType::Add>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using VecBinOp<Nz::ShaderNodes::BinaryType::Add>::VecBinOp;
|
|
||||||
|
|
||||||
QString caption() const override;
|
|
||||||
QString name() const override;
|
|
||||||
|
|
||||||
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VecMul : public VecBinOp<Nz::ShaderNodes::BinaryType::Multiply>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using VecBinOp<Nz::ShaderNodes::BinaryType::Multiply>::VecBinOp;
|
|
||||||
|
|
||||||
QString caption() const override;
|
|
||||||
QString name() const override;
|
|
||||||
|
|
||||||
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VecSub : public VecBinOp<Nz::ShaderNodes::BinaryType::Substract>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using VecBinOp<Nz::ShaderNodes::BinaryType::Substract>::VecBinOp;
|
|
||||||
|
|
||||||
QString caption() const override;
|
|
||||||
QString name() const override;
|
|
||||||
|
|
||||||
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
class VecDiv : public VecBinOp<Nz::ShaderNodes::BinaryType::Divide>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using VecBinOp<Nz::ShaderNodes::BinaryType::Divide>::VecBinOp;
|
|
||||||
|
|
||||||
QString caption() const override;
|
|
||||||
QString name() const override;
|
|
||||||
|
|
||||||
void ApplyOp(const Nz::Vector4f* left, const Nz::Vector4f* right, Nz::Vector4f* output, std::size_t pixelCount) override;
|
|
||||||
};
|
|
||||||
|
|
||||||
#include <ShaderNode/DataModels/VecBinOp.inl>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,131 +0,0 @@
|
||||||
#include <ShaderNode/DataModels/VecBinOp.hpp>
|
|
||||||
#include <Nazara/Shader/ShaderBuilder.hpp>
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
VecBinOp<BinOp>::VecBinOp(ShaderGraph& graph) :
|
|
||||||
ShaderNode(graph)
|
|
||||||
{
|
|
||||||
UpdateOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
Nz::ShaderNodes::ExpressionPtr VecBinOp<BinOp>::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
|
||||||
{
|
|
||||||
assert(count == 2);
|
|
||||||
using BuilderType = typename Nz::ShaderBuilder::template BinOpBuilder<BinOp>;
|
|
||||||
constexpr BuilderType builder;
|
|
||||||
return builder(expressions[0], expressions[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
QtNodes::NodeDataType VecBinOp<BinOp>::dataType(QtNodes::PortType /*portType*/, QtNodes::PortIndex portIndex) const
|
|
||||||
{
|
|
||||||
assert(portIndex == 0 || portIndex == 1);
|
|
||||||
|
|
||||||
return VecData::Type();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
unsigned int VecBinOp<BinOp>::nPorts(QtNodes::PortType portType) const
|
|
||||||
{
|
|
||||||
switch (portType)
|
|
||||||
{
|
|
||||||
case QtNodes::PortType::In: return 2;
|
|
||||||
case QtNodes::PortType::Out: return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
std::shared_ptr<QtNodes::NodeData> VecBinOp<BinOp>::outData(QtNodes::PortIndex port)
|
|
||||||
{
|
|
||||||
assert(port == 0);
|
|
||||||
return m_output;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
void VecBinOp<BinOp>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
|
||||||
{
|
|
||||||
assert(index == 0 || index == 1);
|
|
||||||
|
|
||||||
std::shared_ptr<VecData> castedValue;
|
|
||||||
if (value && value->type().id == VecData::Type().id)
|
|
||||||
castedValue = std::static_pointer_cast<VecData>(value);
|
|
||||||
|
|
||||||
if (index == 0)
|
|
||||||
m_lhs = std::move(castedValue);
|
|
||||||
else
|
|
||||||
m_rhs = std::move(castedValue);
|
|
||||||
|
|
||||||
UpdateOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
QtNodes::NodeValidationState VecBinOp<BinOp>::validationState() const
|
|
||||||
{
|
|
||||||
if (!m_lhs || !m_rhs)
|
|
||||||
return QtNodes::NodeValidationState::Error;
|
|
||||||
|
|
||||||
if (m_lhs->componentCount != m_rhs->componentCount)
|
|
||||||
return QtNodes::NodeValidationState::Error;
|
|
||||||
|
|
||||||
return QtNodes::NodeValidationState::Valid;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
QString VecBinOp<BinOp>::validationMessage() const
|
|
||||||
{
|
|
||||||
if (!m_lhs || !m_rhs)
|
|
||||||
return "Missing operands";
|
|
||||||
|
|
||||||
if (m_lhs->componentCount != m_rhs->componentCount)
|
|
||||||
return "Incompatible components count (left has " + QString::number(m_lhs->componentCount) + ", right has " + QString::number(m_rhs->componentCount) + ")";
|
|
||||||
|
|
||||||
return QString();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
bool VecBinOp<BinOp>::ComputePreview(QPixmap& pixmap)
|
|
||||||
{
|
|
||||||
if (!m_lhs || !m_rhs)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<Nz::ShaderNodes::BinaryType BinOp>
|
|
||||||
void VecBinOp<BinOp>::UpdateOutput()
|
|
||||||
{
|
|
||||||
if (validationState() != QtNodes::NodeValidationState::Valid)
|
|
||||||
{
|
|
||||||
m_output = std::make_shared<VecData>(4);
|
|
||||||
m_output->preview = PreviewValues(1, 1);
|
|
||||||
m_output->preview.Fill(Nz::Vector4f::Zero());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_output = std::make_shared<VecData>(m_lhs->componentCount);
|
|
||||||
|
|
||||||
const PreviewValues& leftPreview = m_lhs->preview;
|
|
||||||
const PreviewValues& rightPreview = m_rhs->preview;
|
|
||||||
std::size_t maxWidth = std::max(leftPreview.GetWidth(), rightPreview.GetWidth());
|
|
||||||
std::size_t maxHeight = std::max(leftPreview.GetHeight(), rightPreview.GetHeight());
|
|
||||||
|
|
||||||
// FIXME: Prevent useless copy
|
|
||||||
PreviewValues leftResized = leftPreview;
|
|
||||||
if (leftResized.GetWidth() != maxWidth || leftResized.GetHeight() != maxHeight)
|
|
||||||
leftResized = leftResized.Resized(maxWidth, maxHeight);
|
|
||||||
|
|
||||||
PreviewValues rightResized = rightPreview;
|
|
||||||
if (rightResized.GetWidth() != maxWidth || rightResized.GetHeight() != maxHeight)
|
|
||||||
rightResized = rightResized.Resized(maxWidth, maxHeight);
|
|
||||||
|
|
||||||
m_output->preview = PreviewValues(maxWidth, maxHeight);
|
|
||||||
ApplyOp(leftResized.GetData(), rightResized.GetData(), m_output->preview.GetData(), maxWidth * maxHeight);
|
|
||||||
|
|
||||||
Q_EMIT dataUpdated(0);
|
|
||||||
|
|
||||||
UpdatePreview();
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_VECTOR_COMPOSITION_HPP
|
||||||
|
#define NAZARA_SHADERNODES_VECTOR_COMPOSITION_HPP
|
||||||
|
|
||||||
|
#include <QtWidgets/QComboBox>
|
||||||
|
#include <QtWidgets/QVBoxLayout>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <ShaderNode/ShaderGraph.hpp>
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
class VecComposition : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VecComposition(ShaderGraph& graph);
|
||||||
|
~VecComposition() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const;
|
||||||
|
|
||||||
|
QString caption() const override;
|
||||||
|
QString name() const override;
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
void UpdateOutput();
|
||||||
|
|
||||||
|
std::array<std::shared_ptr<FloatData>, ComponentCount> m_inputs;
|
||||||
|
std::shared_ptr<VecData> m_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Vec2Composition = VecComposition<2>;
|
||||||
|
using Vec3Composition = VecComposition<3>;
|
||||||
|
using Vec4Composition = VecComposition<4>;
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/VecComposition.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -0,0 +1,192 @@
|
||||||
|
#include <ShaderNode/DataModels/VecComposition.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
#include <QtWidgets/QDoubleSpinBox>
|
||||||
|
#include <QtWidgets/QFormLayout>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
VecComposition<ComponentCount>::VecComposition(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
static_assert(ComponentCount <= s_vectorComponents.size());
|
||||||
|
|
||||||
|
m_output = std::make_shared<VecData>(ComponentCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
Nz::ShaderNodes::NodePtr VecComposition<ComponentCount>::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(count == ComponentCount);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
|
std::array<Nz::ShaderNodes::ExpressionPtr, ComponentCount> expr;
|
||||||
|
for (std::size_t i = 0; i < count; ++i)
|
||||||
|
expr[i] = expressions[i];
|
||||||
|
|
||||||
|
constexpr auto ExpressionType = VecExpressionType<ComponentCount>;
|
||||||
|
return Nz::ShaderBuilder::Cast<ExpressionType>(expr.data(), expr.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QString VecComposition<ComponentCount>::caption() const
|
||||||
|
{
|
||||||
|
static QString caption = "Compose Vector" + QString::number(ComponentCount);
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QString VecComposition<ComponentCount>::name() const
|
||||||
|
{
|
||||||
|
static QString name = "vec_compose" + QString::number(ComponentCount);
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QtNodes::NodeDataType VecComposition<ComponentCount>::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
assert(portIndex >= 0);
|
||||||
|
assert(portIndex < ComponentCount);
|
||||||
|
return FloatData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return VecData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
unsigned int VecComposition<ComponentCount>::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return ComponentCount;
|
||||||
|
case QtNodes::PortType::Out: return 1;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
std::shared_ptr<QtNodes::NodeData> VecComposition<ComponentCount>::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
assert(port == 0);
|
||||||
|
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return m_output;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
void VecComposition<ComponentCount>::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
{
|
||||||
|
assert(index >= 0 && index < ComponentCount);
|
||||||
|
|
||||||
|
if (value && value->type().id == FloatData::Type().id)
|
||||||
|
{
|
||||||
|
assert(dynamic_cast<FloatData*>(value.get()) != nullptr);
|
||||||
|
m_inputs[index] = std::static_pointer_cast<FloatData>(value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_inputs[index].reset();
|
||||||
|
|
||||||
|
UpdateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QtNodes::NodeValidationState VecComposition<ComponentCount>::validationState() const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
{
|
||||||
|
if (!m_inputs[i])
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QString VecComposition<ComponentCount>::validationMessage() const
|
||||||
|
{
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
{
|
||||||
|
if (!m_inputs[i])
|
||||||
|
return "Missing input #" + QString::number(i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
bool VecComposition<ComponentCount>::ComputePreview(QPixmap& pixmap)
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
pixmap = QPixmap::fromImage(m_output->preview.GenerateImage());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
void VecComposition<ComponentCount>::UpdateOutput()
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
{
|
||||||
|
m_output->preview = PreviewValues(1, 1);
|
||||||
|
m_output->preview(0, 0) = Nz::Vector4f::Zero();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::array<PreviewValues, ComponentCount> previewResized;
|
||||||
|
std::size_t maxInputWidth = 0;
|
||||||
|
std::size_t maxInputHeight = 0;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
{
|
||||||
|
// FIXME: Prevent useless copy
|
||||||
|
previewResized[i] = m_inputs[i]->preview;
|
||||||
|
|
||||||
|
maxInputWidth = std::max(maxInputWidth, previewResized[i].GetWidth());
|
||||||
|
maxInputHeight = std::max(maxInputHeight, previewResized[i].GetHeight());
|
||||||
|
}
|
||||||
|
|
||||||
|
PreviewValues& output = m_output->preview;
|
||||||
|
output = PreviewValues(maxInputWidth, maxInputHeight);
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
{
|
||||||
|
if (previewResized[i].GetWidth() != maxInputWidth || previewResized[i].GetHeight() != maxInputHeight)
|
||||||
|
previewResized[i] = previewResized[i].Resized(maxInputWidth, maxInputHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t y = 0; y < maxInputHeight; ++y)
|
||||||
|
{
|
||||||
|
for (std::size_t x = 0; x < maxInputWidth; ++x)
|
||||||
|
{
|
||||||
|
Nz::Vector4f color(0.f, 0.f, 0.f, 1.f);
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
color[i] = previewResized[i](x, y)[0];
|
||||||
|
|
||||||
|
output(x, y) = color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(0);
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,176 @@
|
||||||
|
#include <ShaderNode/DataModels/VecDecomposition.hpp>
|
||||||
|
#include <Nazara/Shader/ShaderBuilder.hpp>
|
||||||
|
#include <ShaderNode/ShaderGraph.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/BoolData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/Matrix4Data.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
#include <QtWidgets/QComboBox>
|
||||||
|
#include <QtWidgets/QFormLayout>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
VecDecomposition::VecDecomposition(ShaderGraph& graph) :
|
||||||
|
ShaderNode(graph)
|
||||||
|
{
|
||||||
|
DisablePreview();
|
||||||
|
DisableCustomVariableName();
|
||||||
|
}
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr VecDecomposition::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
|
{
|
||||||
|
assert(count == 1);
|
||||||
|
assert(outputIndex < m_outputs.size());
|
||||||
|
|
||||||
|
using namespace Nz::ShaderBuilder;
|
||||||
|
using namespace Nz::ShaderNodes;
|
||||||
|
|
||||||
|
return Nz::ShaderBuilder::Swizzle(expressions[0], static_cast<SwizzleComponent>(Nz::UnderlyingCast(SwizzleComponent::First) + outputIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecDecomposition::caption() const
|
||||||
|
{
|
||||||
|
return "Vector decomposition";
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecDecomposition::name() const
|
||||||
|
{
|
||||||
|
return "vec_decompose";
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeDataType VecDecomposition::dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In:
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return VecData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
case QtNodes::PortType::Out:
|
||||||
|
{
|
||||||
|
assert(portIndex >= 0 && portIndex < m_outputs.size());
|
||||||
|
return FloatData::Type();
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int VecDecomposition::nPorts(QtNodes::PortType portType) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return 1;
|
||||||
|
case QtNodes::PortType::Out: return m_outputs.size();
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecDecomposition::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
assert(portIndex >= 0 && portIndex < s_vectorComponents.size());
|
||||||
|
|
||||||
|
return QString(QChar(s_vectorComponents[portIndex]));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VecDecomposition::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
switch (portType)
|
||||||
|
{
|
||||||
|
case QtNodes::PortType::In: return false;
|
||||||
|
case QtNodes::PortType::Out: return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(false);
|
||||||
|
throw std::runtime_error("Invalid port type");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> VecDecomposition::outData(QtNodes::PortIndex port)
|
||||||
|
{
|
||||||
|
if (!m_input)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return m_outputs[port];
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecDecomposition::setInData(std::shared_ptr<QtNodes::NodeData> value, int index)
|
||||||
|
{
|
||||||
|
assert(index == 0);
|
||||||
|
|
||||||
|
std::shared_ptr<VecData> castedValue;
|
||||||
|
if (value && value->type().id == VecData::Type().id)
|
||||||
|
castedValue = std::static_pointer_cast<VecData>(value);
|
||||||
|
|
||||||
|
m_input = std::move(castedValue);
|
||||||
|
|
||||||
|
UpdateOutputs();
|
||||||
|
}
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState VecDecomposition::validationState() const
|
||||||
|
{
|
||||||
|
if (!m_input)
|
||||||
|
return QtNodes::NodeValidationState::Error;
|
||||||
|
|
||||||
|
return QtNodes::NodeValidationState::Valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString VecDecomposition::validationMessage() const
|
||||||
|
{
|
||||||
|
if (!m_input)
|
||||||
|
return "Missing input";
|
||||||
|
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VecDecomposition::UpdateOutputs()
|
||||||
|
{
|
||||||
|
if (validationState() != QtNodes::NodeValidationState::Valid)
|
||||||
|
{
|
||||||
|
auto dummy = std::make_shared<FloatData>();
|
||||||
|
dummy->preview = PreviewValues(1, 1);
|
||||||
|
dummy->preview.Fill(Nz::Vector4f::Zero());
|
||||||
|
|
||||||
|
m_outputs.fill(dummy);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t previewWidth = m_input->preview.GetWidth();
|
||||||
|
std::size_t previewHeight = m_input->preview.GetHeight();
|
||||||
|
std::size_t pixelCount = previewWidth * previewHeight;
|
||||||
|
|
||||||
|
for (std::size_t i = 0; i < m_input->componentCount; ++i)
|
||||||
|
{
|
||||||
|
m_outputs[i] = std::make_shared<FloatData>();
|
||||||
|
m_outputs[i]->preview = PreviewValues(previewWidth, previewHeight);
|
||||||
|
|
||||||
|
const Nz::Vector4f* inputData = m_input->preview.GetData();
|
||||||
|
Nz::Vector4f* outputData = m_outputs[i]->preview.GetData();
|
||||||
|
for (std::size_t j = 0; j < pixelCount; ++j)
|
||||||
|
{
|
||||||
|
const Nz::Vector4f& input = *inputData++;
|
||||||
|
|
||||||
|
*outputData++ = Nz::Vector4f(input[i], input[i], input[i], input[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_EMIT dataUpdated(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (std::size_t i = m_input->componentCount; i < m_outputs.size(); ++i)
|
||||||
|
m_outputs[i] = nullptr;
|
||||||
|
|
||||||
|
UpdatePreview();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_SHADERNODES_VECTOR_DECOMPOSITION_HPP
|
||||||
|
#define NAZARA_SHADERNODES_VECTOR_DECOMPOSITION_HPP
|
||||||
|
|
||||||
|
#include <QtWidgets/QComboBox>
|
||||||
|
#include <QtWidgets/QVBoxLayout>
|
||||||
|
#include <QtWidgets/QLabel>
|
||||||
|
#include <ShaderNode/ShaderGraph.hpp>
|
||||||
|
#include <ShaderNode/DataModels/ShaderNode.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/FloatData.hpp>
|
||||||
|
#include <ShaderNode/DataTypes/VecData.hpp>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
|
class VecDecomposition : public ShaderNode
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VecDecomposition(ShaderGraph& graph);
|
||||||
|
~VecDecomposition() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
|
QString caption() const override;
|
||||||
|
QString name() const override;
|
||||||
|
|
||||||
|
QtNodes::NodeDataType dataType(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
unsigned int nPorts(QtNodes::PortType portType) const override;
|
||||||
|
|
||||||
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
|
||||||
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
|
void setInData(std::shared_ptr<QtNodes::NodeData> value, int index) override;
|
||||||
|
|
||||||
|
QtNodes::NodeValidationState validationState() const override;
|
||||||
|
QString validationMessage() const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void UpdateOutputs();
|
||||||
|
|
||||||
|
std::shared_ptr<VecData> m_input;
|
||||||
|
std::array<std::shared_ptr<FloatData>, 4> m_outputs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include <ShaderNode/DataModels/VecDecomposition.inl>
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -8,9 +8,11 @@ ShaderNode(graph)
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr VecDot::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr VecDot::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
using namespace Nz::ShaderNodes;
|
using namespace Nz::ShaderNodes;
|
||||||
return IntrinsicCall::Build(IntrinsicType::DotProduct, { expressions[0], expressions[1] });
|
return IntrinsicCall::Build(IntrinsicType::DotProduct, { expressions[0], expressions[1] });
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class VecDot : public ShaderNode
|
||||||
VecDot(ShaderGraph& graph);
|
VecDot(ShaderGraph& graph);
|
||||||
~VecDot() = default;
|
~VecDot() = default;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,11 @@ ShaderNode(graph)
|
||||||
UpdateOutput();
|
UpdateOutput();
|
||||||
}
|
}
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr VecFloatMul::GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const
|
Nz::ShaderNodes::NodePtr VecFloatMul::BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 2);
|
assert(count == 2);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
using namespace Nz::ShaderNodes;
|
using namespace Nz::ShaderNodes;
|
||||||
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
|
return BinaryOp::Build(BinaryType::Multiply, expressions[0], expressions[1]);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class VecFloatMul : public ShaderNode
|
||||||
VecFloatMul(ShaderGraph& graph);
|
VecFloatMul(ShaderGraph& graph);
|
||||||
~VecFloatMul() = default;
|
~VecFloatMul() = default;
|
||||||
|
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
#include <ShaderNode/DataModels/VecValue.hpp>
|
|
||||||
|
|
@ -18,6 +18,9 @@ class VecValue : public ShaderNode
|
||||||
VecValue(ShaderGraph& graph);
|
VecValue(ShaderGraph& graph);
|
||||||
~VecValue() = default;
|
~VecValue() = default;
|
||||||
|
|
||||||
|
Nz::ShaderNodes::NodePtr BuildNode(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count, std::size_t outputIndex) const override;
|
||||||
|
void BuildNodeEdition(QFormLayout* layout) override;
|
||||||
|
|
||||||
QString caption() const override;
|
QString caption() const override;
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
|
|
||||||
|
|
@ -27,9 +30,8 @@ class VecValue : public ShaderNode
|
||||||
|
|
||||||
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
std::shared_ptr<QtNodes::NodeData> outData(QtNodes::PortIndex port) override;
|
||||||
|
|
||||||
void BuildNodeEdition(QFormLayout* layout) override;
|
QString portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
|
bool portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const override;
|
||||||
Nz::ShaderNodes::ExpressionPtr GetExpression(Nz::ShaderNodes::ExpressionPtr* expressions, std::size_t count) const override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool ComputePreview(QPixmap& pixmap) override;
|
bool ComputePreview(QPixmap& pixmap) override;
|
||||||
|
|
|
||||||
|
|
@ -75,6 +75,33 @@ std::shared_ptr<QtNodes::NodeData> VecValue<ComponentCount>::outData(QtNodes::Po
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
QString VecValue<ComponentCount>::portCaption(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
assert(portType == QtNodes::PortType::Out);
|
||||||
|
|
||||||
|
QString caption = "vec" + QString::number(ComponentCount) + "(";
|
||||||
|
for (std::size_t i = 0; i < ComponentCount; ++i)
|
||||||
|
{
|
||||||
|
if (i > 0)
|
||||||
|
caption += ", ";
|
||||||
|
|
||||||
|
caption += QString::number(m_value[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
caption += ")";
|
||||||
|
|
||||||
|
return caption;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<std::size_t ComponentCount>
|
||||||
|
bool VecValue<ComponentCount>::portCaptionVisible(QtNodes::PortType portType, QtNodes::PortIndex portIndex) const
|
||||||
|
{
|
||||||
|
assert(portIndex == 0);
|
||||||
|
return portType == QtNodes::PortType::Out;
|
||||||
|
}
|
||||||
|
|
||||||
template<std::size_t ComponentCount>
|
template<std::size_t ComponentCount>
|
||||||
void VecValue<ComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
void VecValue<ComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
{
|
{
|
||||||
|
|
@ -100,9 +127,10 @@ void VecValue<ComponentCount>::BuildNodeEdition(QFormLayout* layout)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<std::size_t ComponentCount>
|
template<std::size_t ComponentCount>
|
||||||
Nz::ShaderNodes::ExpressionPtr VecValue<ComponentCount>::GetExpression(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count) const
|
Nz::ShaderNodes::NodePtr VecValue<ComponentCount>::BuildNode(Nz::ShaderNodes::ExpressionPtr* /*expressions*/, std::size_t count, std::size_t outputIndex) const
|
||||||
{
|
{
|
||||||
assert(count == 0);
|
assert(count == 0);
|
||||||
|
assert(outputIndex == 0);
|
||||||
|
|
||||||
return Nz::ShaderBuilder::Constant(m_value);
|
return Nz::ShaderBuilder::Constant(m_value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue