diff --git a/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx b/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx
new file mode 100644
index 0000000000..4fbf6d12d9
--- /dev/null
+++ b/resources/Materials/TestSuite/stdlib/texture/texcoord.mtlx
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
index 3cb8eb6237..66dc69f668 100644
--- a/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
+++ b/resources/Materials/TestSuite/stdlib/upgrade/syntax_1_37.mtlx
@@ -4,61 +4,110 @@
Examples of MaterialX 1.37 syntax
-->
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/source/MaterialXCore/Document.cpp b/source/MaterialXCore/Document.cpp
index 0449189873..80143bb9c8 100644
--- a/source/MaterialXCore/Document.cpp
+++ b/source/MaterialXCore/Document.cpp
@@ -1040,39 +1040,7 @@ void Document::upgradeVersion()
}
}
- // Update atan2 interface and rotate3d interface
- const string ATAN2 = "atan2";
- const string IN1 = "in1";
- const string IN2 = "in2";
- const string ROTATE3D = "rotate3d";
- const string AXIS = "axis";
- const string INPUT_ONE = "1.0";
-
- // Update nodedefs
- bool upgradeAtan2Instances = false;
- for (auto nodedef : getMatchingNodeDefs(ATAN2))
- {
- InputPtr input = nodedef->getInput(IN1);
- InputPtr input2 = nodedef->getInput(IN2);
- string inputValue = input->getValueString();
- // Only flip value if nodedef value is the previous versions.
- if (inputValue == INPUT_ONE)
- {
- input->setValueString(input2->getValueString());
- input2->setValueString(inputValue);
- upgradeAtan2Instances = true;
- }
- }
- for (auto nodedef : getMatchingNodeDefs(ROTATE3D))
- {
- ElementPtr axis = nodedef->getChild(AXIS);
- if (axis)
- {
- nodedef->changeChildCategory(axis, "input");
- }
- }
-
- // Update BSDF interfaces
+ // Define BSDF node pairs.
using StringPair = std::pair;
const StringPair DIELECTRIC_BRDF = { "dielectric_brdf", "dielectric_bsdf" };
const StringPair DIELECTRIC_BTDF = { "dielectric_btdf", "dielectric_bsdf" };
@@ -1085,57 +1053,11 @@ void Document::upgradeVersion()
const StringPair SUBSURFACE_BRDF = { "subsurface_brdf", "subsurface_bsdf" };
const StringPair THIN_FILM_BRDF = { "thin_film_brdf", "thin_film_bsdf" };
- const string SCATTER_MODE = "scatter_mode";
- const string BSDF = "BSDF";
- const string LAYER = "layer";
- const string TOP = "top";
- const string BASE = "base";
- const string INTERIOR = "interior";
- const string ARTISTIC_IOR = "artistic_ior";
- const string COMPLEX_IOR = "complex_ior";
- const string REFLECTIVITY = "reflectivity";
- const string EDGE_COLOR = "edge_color";
- const string IOR = "ior";
- const string EXTINCTION = "extinction";
- const string COLOR3 = "color3";
- const string VECTOR3 = "vector3";
- const string CONVERT = "convert";
- const string IN = "in";
-
- // Function for upgrading BSDF nodedef.
- auto upgradeBsdfNodeDef = [SCATTER_MODE](NodeDefPtr nodedef, const string& newCategory, bool addScatterMode = false)
- {
- if (nodedef)
- {
- nodedef->setName(newCategory);
- if (addScatterMode)
- {
- InputPtr mode = nodedef->addInput(SCATTER_MODE, STRING_TYPE_STRING);
- mode->setIsUniform(true);
- mode->setValueString("R");
- mode->setAttribute("enum", "R,T,RT");
- }
- }
- };
-
- // Update nodedefs.
- upgradeBsdfNodeDef(getNodeDef(DIELECTRIC_BRDF.first), DIELECTRIC_BRDF.second, true);
- upgradeBsdfNodeDef(getNodeDef(GENERALIZED_SCHLICK_BRDF.first), GENERALIZED_SCHLICK_BRDF.second, true);
- upgradeBsdfNodeDef(getNodeDef(CONDUCTOR_BRDF.first), CONDUCTOR_BRDF.second);
- upgradeBsdfNodeDef(getNodeDef(SHEEN_BRDF.first), SHEEN_BRDF.second);
- upgradeBsdfNodeDef(getNodeDef(DIFFUSE_BRDF.first), DIFFUSE_BRDF.second);
- upgradeBsdfNodeDef(getNodeDef(BURLEY_DIFFUSE_BRDF.first), BURLEY_DIFFUSE_BRDF.second);
- upgradeBsdfNodeDef(getNodeDef(DIFFUSE_BTDF.first), DIFFUSE_BTDF.second);
- upgradeBsdfNodeDef(getNodeDef(SUBSURFACE_BRDF.first), SUBSURFACE_BRDF.second);
- upgradeBsdfNodeDef(getNodeDef(THIN_FILM_BRDF.first), THIN_FILM_BRDF.second);
- removeNodeDef(DIELECTRIC_BTDF.first);
- removeNodeDef(COMPLEX_IOR);
-
// Function for upgrading old nested layering setup
// to new setup with layer operators.
- auto upgradeBsdfLayering = [TOP, BASE, LAYER, BSDF](NodePtr node)
+ auto upgradeBsdfLayering = [](NodePtr node)
{
- InputPtr base = node->getInput(BASE);
+ InputPtr base = node->getInput("base");
if (base)
{
NodePtr baseNode = base->getConnectedNode();
@@ -1146,13 +1068,13 @@ void Document::upgradeVersion()
// so we don't need to update any connection references.
const string oldName = node->getName();
node->setName(oldName + "__layer_top");
- NodePtr layer = parent->addNode(LAYER, oldName, BSDF);
- InputPtr layerTop = layer->addInput(TOP, BSDF);
- InputPtr layerBase = layer->addInput(BASE, BSDF);
+ NodePtr layer = parent->addNode("layer", oldName, "BSDF");
+ InputPtr layerTop = layer->addInput("top", "BSDF");
+ InputPtr layerBase = layer->addInput("base", "BSDF");
layerTop->setConnectedNode(node);
layerBase->setConnectedNode(baseNode);
}
- node->removeInput(BASE);
+ node->removeInput("base");
}
};
@@ -1177,31 +1099,31 @@ void Document::upgradeVersion()
continue;
}
const string& nodeCategory = node->getCategory();
- if (upgradeAtan2Instances && nodeCategory == ATAN2)
+ if (nodeCategory == "atan2")
{
- InputPtr input = node->getInput(IN1);
- InputPtr input2 = node->getInput(IN2);
+ InputPtr input = node->getInput("in1");
+ InputPtr input2 = node->getInput("in2");
if (input && input2)
{
input->setName(EMPTY_STRING);
- input2->setName(IN1);
- input->setName(IN2);
+ input2->setName("in1");
+ input->setName("in2");
}
else
{
if (input)
{
- input->setName(IN2);
+ input->setName("in2");
}
if (input2)
{
- input2->setName(IN1);
+ input2->setName("in1");
}
}
}
- else if (nodeCategory == ROTATE3D)
+ else if (nodeCategory == "rotate3d")
{
- ElementPtr axis = node->getChild(AXIS);
+ ElementPtr axis = node->getChild("axis");
if (axis)
{
node->changeChildCategory(axis, "input");
@@ -1215,8 +1137,8 @@ void Document::upgradeVersion()
else if (nodeCategory == DIELECTRIC_BTDF.first)
{
node->setCategory(DIELECTRIC_BTDF.second);
- node->removeInput(INTERIOR);
- InputPtr mode = node->addInput(SCATTER_MODE, STRING_TYPE_STRING);
+ node->removeInput("interior");
+ InputPtr mode = node->addInput("scatter_mode", STRING_TYPE_STRING);
mode->setValueString("T");
}
else if (nodeCategory == GENERALIZED_SCHLICK_BRDF.first)
@@ -1240,32 +1162,32 @@ void Document::upgradeVersion()
// Create an artistic_ior node to convert from artistic to physical parameterization.
GraphElementPtr parent = node->getParent()->asA();
- NodePtr artisticIor = parent->addNode(ARTISTIC_IOR, node->getName() + "__artistic_ior", "multioutput");
- OutputPtr artisticIor_ior = artisticIor->addOutput(IOR, COLOR3);
- OutputPtr artisticIor_extinction = artisticIor->addOutput(EXTINCTION, COLOR3);
+ NodePtr artisticIor = parent->addNode("artistic_ior", node->getName() + "__artistic_ior", "multioutput");
+ OutputPtr artisticIor_ior = artisticIor->addOutput("ior", "color3");
+ OutputPtr artisticIor_extinction = artisticIor->addOutput("extinction", "color3");
// Copy values and connections from conductor node to artistic_ior node.
- InputPtr reflectivity = node->getInput(REFLECTIVITY);
+ InputPtr reflectivity = node->getInput("reflectivity");
if (reflectivity)
{
- InputPtr artisticIor_reflectivity = artisticIor->addInput(REFLECTIVITY, COLOR3);
+ InputPtr artisticIor_reflectivity = artisticIor->addInput("reflectivity", "color3");
copyAttributes(reflectivity, artisticIor_reflectivity);
}
- InputPtr edge_color = node->getInput(EDGE_COLOR);
+ InputPtr edge_color = node->getInput("edge_color");
if (edge_color)
{
- InputPtr artisticIor_edge_color = artisticIor->addInput(EDGE_COLOR, COLOR3);
+ InputPtr artisticIor_edge_color = artisticIor->addInput("edge_color", "color3");
copyAttributes(edge_color, artisticIor_edge_color);
}
// Update the parameterization on the conductor node
// and connect it to the artistic_ior node.
- node->removeInput(REFLECTIVITY);
- node->removeInput(EDGE_COLOR);
- InputPtr ior = node->addInput(IOR, COLOR3);
+ node->removeInput("reflectivity");
+ node->removeInput("edge_color");
+ InputPtr ior = node->addInput("ior", "color3");
ior->setNodeName(artisticIor->getName());
ior->setOutputString(artisticIor_ior->getName());
- InputPtr extinction = node->addInput(EXTINCTION, COLOR3);
+ InputPtr extinction = node->addInput("extinction", "color3");
extinction->setNodeName(artisticIor->getName());
extinction->setOutputString(artisticIor_extinction->getName());
}
@@ -1285,17 +1207,17 @@ void Document::upgradeVersion()
{
node->setCategory(SUBSURFACE_BRDF.second);
}
- else if (nodeCategory == ARTISTIC_IOR)
+ else if (nodeCategory == "artistic_ior")
{
- OutputPtr ior = node->getOutput(IOR);
+ OutputPtr ior = node->getOutput("ior");
if (ior)
{
- ior->setType(COLOR3);
+ ior->setType("color3");
}
- OutputPtr extinction = node->getOutput(EXTINCTION);
+ OutputPtr extinction = node->getOutput("extinction");
if (extinction)
{
- extinction->setType(COLOR3);
+ extinction->setType("color3");
}
}
@@ -1306,18 +1228,18 @@ void Document::upgradeVersion()
// since we can't modify the graph while traversing it.
for (InputPtr input : node->getInputs())
{
- if (input->getOutputString() == IOR && input->getType() == VECTOR3)
+ if (input->getOutputString() == "ior" && input->getType() == "vector3")
{
NodePtr connectedNode = input->getConnectedNode();
- if (connectedNode && connectedNode->getCategory() == ARTISTIC_IOR)
+ if (connectedNode && connectedNode->getCategory() == "artistic_ior")
{
artisticIorConnections.push_back(input);
}
}
- else if (input->getOutputString() == EXTINCTION && input->getType() == VECTOR3)
+ else if (input->getOutputString() == "extinction" && input->getType() == "vector3")
{
NodePtr connectedNode = input->getConnectedNode();
- if (connectedNode && connectedNode->getCategory() == ARTISTIC_IOR)
+ if (connectedNode && connectedNode->getCategory() == "artistic_ior")
{
artisticExtConnections.push_back(input);
}
@@ -1331,10 +1253,10 @@ void Document::upgradeVersion()
NodePtr artisticIorNode = input->getConnectedNode();
ElementPtr node = input->getParent();
GraphElementPtr parent = node->getParent()->asA();
- NodePtr convert = parent->addNode(CONVERT, node->getName() + "__convert_ior", VECTOR3);
- InputPtr convertInput = convert->addInput(IN, COLOR3);
+ NodePtr convert = parent->addNode("convert", node->getName() + "__convert_ior", "vector3");
+ InputPtr convertInput = convert->addInput("in", "color3");
convertInput->setNodeName(artisticIorNode->getName());
- convertInput->setOutputString(IOR);
+ convertInput->setOutputString("ior");
input->setNodeName(convert->getName());
input->removeAttribute(PortElement::OUTPUT_ATTRIBUTE);
}
@@ -1343,10 +1265,10 @@ void Document::upgradeVersion()
NodePtr artisticIorNode = input->getConnectedNode();
ElementPtr node = input->getParent();
GraphElementPtr parent = node->getParent()->asA();
- NodePtr convert = parent->addNode(CONVERT, node->getName() + "__convert_extinction", VECTOR3);
- InputPtr convertInput = convert->addInput(IN, COLOR3);
+ NodePtr convert = parent->addNode("convert", node->getName() + "__convert_extinction", "vector3");
+ InputPtr convertInput = convert->addInput("in", "color3");
convertInput->setNodeName(artisticIorNode->getName());
- convertInput->setOutputString(EXTINCTION);
+ convertInput->setOutputString("extinction");
input->setNodeName(convert->getName());
input->removeAttribute(PortElement::OUTPUT_ATTRIBUTE);
}
diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp
index 839f591aa5..ec5e48d4ec 100644
--- a/source/MaterialXGenGlsl/GlslShaderGenerator.cpp
+++ b/source/MaterialXGenGlsl/GlslShaderGenerator.cpp
@@ -10,7 +10,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -23,9 +22,6 @@
#include
#include
#include
-#include
-#include
-#include
#include
#include
@@ -34,6 +30,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -174,8 +172,8 @@ GlslShaderGenerator::GlslShaderGenerator() :
//
registerImplementation("IM_bitangent_vector3_" + GlslShaderGenerator::TARGET, BitangentNodeGlsl::create);
//
- registerImplementation("IM_texcoord_vector2_" + GlslShaderGenerator::TARGET, TexCoordNodeGlsl::create);
- registerImplementation("IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, TexCoordNodeGlsl::create);
+ registerImplementation("IM_texcoord_vector2_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create);
+ registerImplementation("IM_texcoord_vector3_" + GlslShaderGenerator::TARGET, HwTexCoordNode::create);
//
registerImplementation("IM_geomcolor_float_" + GlslShaderGenerator::TARGET, GeomColorNodeGlsl::create);
registerImplementation("IM_geomcolor_color3_" + GlslShaderGenerator::TARGET, GeomColorNodeGlsl::create);
@@ -228,13 +226,13 @@ GlslShaderGenerator::GlslShaderGenerator() :
registerImplementation(elementNames, BlurNodeGlsl::create);
//
elementNames = {
@@ -902,11 +900,6 @@ ShaderNodeImplPtr GlslShaderGenerator::getImplementation(const NodeDef& nodedef,
}
const string GlslImplementation::SPACE = "space";
-const string GlslImplementation::TO_SPACE = "tospace";
-const string GlslImplementation::FROM_SPACE = "fromspace";
-const string GlslImplementation::WORLD = "world";
-const string GlslImplementation::OBJECT = "object";
-const string GlslImplementation::MODEL = "model";
const string GlslImplementation::INDEX = "index";
const string GlslImplementation::GEOMPROP = "geomprop";
diff --git a/source/MaterialXGenGlsl/GlslShaderGenerator.h b/source/MaterialXGenGlsl/GlslShaderGenerator.h
index 1df2ace543..acc8b0d6ee 100644
--- a/source/MaterialXGenGlsl/GlslShaderGenerator.h
+++ b/source/MaterialXGenGlsl/GlslShaderGenerator.h
@@ -45,7 +45,7 @@ class MX_GENGLSL_API GlslShaderGenerator : public HwShaderGenerator
ShaderNodeImplPtr getImplementation(const NodeDef& nodedef, GenContext& context) const override;
/// Determine the prefix of vertex data variables.
- virtual string getVertexDataPrefix(const VariableBlock& vertexData) const;
+ string getVertexDataPrefix(const VariableBlock& vertexData) const override;
public:
/// Unique identifier for this generator target
@@ -110,11 +110,6 @@ class MX_GENGLSL_API GlslImplementation : public ShaderNodeImpl
/// Internal string constants
static const string SPACE;
- static const string TO_SPACE;
- static const string FROM_SPACE;
- static const string WORLD;
- static const string OBJECT;
- static const string MODEL;
static const string INDEX;
static const string GEOMPROP;
};
diff --git a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp
deleted file mode 100644
index 846c77f5b7..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TexCoordNodeGlsl::create()
-{
- return std::make_shared();
-}
-
-void TexCoordNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
-{
- const ShaderOutput* output = node.getOutput();
- const ShaderInput* indexInput = node.getInput(INDEX);
- const string index = indexInput ? indexInput->getValue()->getValueString() : "0";
-
- ShaderStage& vs = shader.getStage(Stage::VERTEX);
- ShaderStage& ps = shader.getStage(Stage::PIXEL);
-
- addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs);
- addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps);
-}
-
-void TexCoordNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- const GlslShaderGenerator& shadergen = static_cast(context.getShaderGenerator());
-
- const ShaderInput* indexInput = node.getInput(INDEX);
- const string index = indexInput ? indexInput->getValue()->getValueString() : "0";
- const string variable = HW::T_TEXCOORD + "_" + index;
-
- DEFINE_SHADER_STAGE(stage, Stage::VERTEX)
- {
- VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA);
- const string prefix = shadergen.getVertexDataPrefix(vertexData);
- ShaderPort* texcoord = vertexData[variable];
- if (!texcoord->isEmitted())
- {
- shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage);
- texcoord->setEmitted();
- }
- }
-
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA);
- const string prefix = shadergen.getVertexDataPrefix(vertexData);
- ShaderPort* texcoord = vertexData[variable];
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(node.getOutput(), true, false, context, stage);
- shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp
deleted file mode 100644
index 0800fb4bf3..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformNormalNodeGlsl::create()
-{
- return std::make_shared();
-}
-
-void TransformNormalNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- TransformVectorNodeGlsl::emitFunctionCall(node, context, stage);
-
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- const ShaderOutput* output = node.getOutput();
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(output, false, false, context, stage);
- shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-const string& TransformNormalNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const
-{
- if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD)
- {
- return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX;
- }
- else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT))
- {
- return HW::T_WORLD_TRANSPOSE_MATRIX;
- }
- return EMPTY_STRING;
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h
deleted file mode 100644
index f08ec564d9..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformNormalNodeGlsl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMNORMALNODEGLSL_H
-#define MATERIALX_TRANSFORMNORMALNODEGLSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformNormal node implementation for GLSL
-class MX_GENGLSL_API TransformNormalNodeGlsl : public TransformVectorNodeGlsl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- const string& getMatrix(const string& fromSpace, const string& toSpace) const override;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp
deleted file mode 100644
index 1570939bfe..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformPointNodeGlsl::create()
-{
- return std::make_shared();
-}
-
-string TransformPointNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const
-{
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)";
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h
deleted file mode 100644
index eb366d8190..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformPointNodeGlsl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMPOINTNODEGLSL_H
-#define MATERIALX_TRANSFORMPOINTNODEGLSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformPoint node implementation for GLSL
-class MX_GENGLSL_API TransformPointNodeGlsl : public TransformVectorNodeGlsl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp
deleted file mode 100644
index df1e921497..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformVectorNodeGlsl::create()
-{
- return std::make_shared();
-}
-
-void TransformVectorNodeGlsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
-{
- const ShaderInput* toSpaceInput = node.getInput(TO_SPACE);
- string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE);
- string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const string& matrix = getMatrix(fromSpace, toSpace);
- if (!matrix.empty())
- {
- ShaderStage& ps = shader.getStage(Stage::PIXEL);
- addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps);
- }
-}
-
-void TransformVectorNodeGlsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- const ShaderGenerator& shadergen = context.getShaderGenerator();
-
- const ShaderInput* inInput = node.getInput("in");
- if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4)
- {
- throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4.");
- }
-
- const ShaderInput* toSpaceInput = node.getInput(TO_SPACE);
- string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE);
- string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(node.getOutput(), true, false, context, stage);
- shadergen.emitString(" = (", stage);
- const string& matrix = getMatrix(fromSpace, toSpace);
- if (!matrix.empty())
- {
- shadergen.emitString(matrix + " * ", stage);
- }
- shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage);
- shadergen.emitString(").xyz", stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-const string& TransformVectorNodeGlsl::getMatrix(const string& fromSpace, const string& toSpace) const
-{
- if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD)
- {
- return HW::T_WORLD_MATRIX;
- }
- else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT))
- {
- return HW::T_WORLD_INVERSE_MATRIX;
- }
- return EMPTY_STRING;
-}
-
-string TransformVectorNodeGlsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const
-{
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- return "vec4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)";
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h b/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h
deleted file mode 100644
index e9861650b3..0000000000
--- a/source/MaterialXGenGlsl/Nodes/TransformVectorNodeGlsl.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMVECTORNODEGLSL_H
-#define MATERIALX_TRANSFORMVECTORNODEGLSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformVector node implementation for GLSL
-class MX_GENGLSL_API TransformVectorNodeGlsl : public GlslImplementation
-{
- public:
- static ShaderNodeImplPtr create();
-
- void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override;
-
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- protected:
- virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const;
- virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenMsl/MslShaderGenerator.cpp b/source/MaterialXGenMsl/MslShaderGenerator.cpp
index 0d97e8408f..ea3fb7112d 100644
--- a/source/MaterialXGenMsl/MslShaderGenerator.cpp
+++ b/source/MaterialXGenMsl/MslShaderGenerator.cpp
@@ -10,7 +10,6 @@
#include
#include
#include
-#include
#include
#include
#include
@@ -23,9 +22,6 @@
#include
#include
#include
-#include
-#include
-#include
#include
#include
@@ -34,6 +30,8 @@
#include
#include
#include
+#include
+#include
#include
#include
#include
@@ -178,8 +176,8 @@ MslShaderGenerator::MslShaderGenerator() :
//
registerImplementation("IM_bitangent_vector3_" + MslShaderGenerator::TARGET, BitangentNodeMsl::create);
//
- registerImplementation("IM_texcoord_vector2_" + MslShaderGenerator::TARGET, TexCoordNodeMsl::create);
- registerImplementation("IM_texcoord_vector3_" + MslShaderGenerator::TARGET, TexCoordNodeMsl::create);
+ registerImplementation("IM_texcoord_vector2_" + MslShaderGenerator::TARGET, HwTexCoordNode::create);
+ registerImplementation("IM_texcoord_vector3_" + MslShaderGenerator::TARGET, HwTexCoordNode::create);
//
registerImplementation("IM_geomcolor_float_" + MslShaderGenerator::TARGET, GeomColorNodeMsl::create);
registerImplementation("IM_geomcolor_color3_" + MslShaderGenerator::TARGET, GeomColorNodeMsl::create);
@@ -232,13 +230,13 @@ MslShaderGenerator::MslShaderGenerator() :
registerImplementation(elementNames, BlurNodeMsl::create);
//
elementNames = {
@@ -1404,11 +1402,6 @@ ShaderNodeImplPtr MslShaderGenerator::getImplementation(const NodeDef& nodedef,
}
const string MslImplementation::SPACE = "space";
-const string MslImplementation::TO_SPACE = "tospace";
-const string MslImplementation::FROM_SPACE = "fromspace";
-const string MslImplementation::WORLD = "world";
-const string MslImplementation::OBJECT = "object";
-const string MslImplementation::MODEL = "model";
const string MslImplementation::INDEX = "index";
const string MslImplementation::GEOMPROP = "geomprop";
diff --git a/source/MaterialXGenMsl/MslShaderGenerator.h b/source/MaterialXGenMsl/MslShaderGenerator.h
index ecbf37d7a6..21817db735 100644
--- a/source/MaterialXGenMsl/MslShaderGenerator.h
+++ b/source/MaterialXGenMsl/MslShaderGenerator.h
@@ -48,7 +48,7 @@ class MX_GENMSL_API MslShaderGenerator : public HwShaderGenerator
ShaderNodeImplPtr getImplementation(const NodeDef& nodedef, GenContext& context) const override;
/// Determine the prefix of vertex data variables.
- virtual string getVertexDataPrefix(const VariableBlock& vertexData) const;
+ string getVertexDataPrefix(const VariableBlock& vertexData) const override;
public:
/// Unique identifier for this generator target
@@ -137,11 +137,6 @@ class MX_GENMSL_API MslImplementation : public ShaderNodeImpl
/// Internal string constants
static const string SPACE;
- static const string TO_SPACE;
- static const string FROM_SPACE;
- static const string WORLD;
- static const string OBJECT;
- static const string MODEL;
static const string INDEX;
static const string GEOMPROP;
};
diff --git a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp
deleted file mode 100644
index a88152eb82..0000000000
--- a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.cpp
+++ /dev/null
@@ -1,62 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TexCoordNodeMsl::create()
-{
- return std::make_shared();
-}
-
-void TexCoordNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
-{
- const ShaderOutput* output = node.getOutput();
- const ShaderInput* indexInput = node.getInput(INDEX);
- const string index = indexInput ? indexInput->getValue()->getValueString() : "0";
-
- ShaderStage& vs = shader.getStage(Stage::VERTEX);
- ShaderStage& ps = shader.getStage(Stage::PIXEL);
-
- addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs);
- addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps);
-}
-
-void TexCoordNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- const MslShaderGenerator& shadergen = static_cast(context.getShaderGenerator());
-
- const ShaderInput* indexInput = node.getInput(INDEX);
- const string index = indexInput ? indexInput->getValue()->getValueString() : "0";
- const string variable = HW::T_TEXCOORD + "_" + index;
-
- DEFINE_SHADER_STAGE(stage, Stage::VERTEX)
- {
- VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA);
- const string prefix = shadergen.getVertexDataPrefix(vertexData);
- ShaderPort* texcoord = vertexData[variable];
- if (!texcoord->isEmitted())
- {
- shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage);
- texcoord->setEmitted();
- }
- }
-
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA);
- const string prefix = shadergen.getVertexDataPrefix(vertexData);
- ShaderPort* texcoord = vertexData[variable];
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(node.getOutput(), true, false, context, stage);
- shadergen.emitString(" = " + prefix + texcoord->getVariable(), stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h b/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h
deleted file mode 100644
index 6c227cc63b..0000000000
--- a/source/MaterialXGenMsl/Nodes/TexCoordNodeMsl.h
+++ /dev/null
@@ -1,26 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TEXCOORDNODEMSL_H
-#define MATERIALX_TEXCOORDNODEMSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TexCoord node implementation for MSL
-class MX_GENMSL_API TexCoordNodeMsl : public MslImplementation
-{
- public:
- static ShaderNodeImplPtr create();
-
- void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override;
-
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp
deleted file mode 100644
index 98810c025b..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformNormalNodeMsl::create()
-{
- return std::make_shared();
-}
-
-void TransformNormalNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- TransformVectorNodeMsl::emitFunctionCall(node, context, stage);
-
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- const ShaderOutput* output = node.getOutput();
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(output, false, false, context, stage);
- shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-const string& TransformNormalNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const
-{
- if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD)
- {
- return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX;
- }
- else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT))
- {
- return HW::T_WORLD_TRANSPOSE_MATRIX;
- }
- return EMPTY_STRING;
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h
deleted file mode 100644
index 603ba3771c..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformNormalNodeMsl.h
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMNORMALNODEMSL_H
-#define MATERIALX_TRANSFORMNORMALNODEMSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformNormal node implementation for MSL
-class MX_GENMSL_API TransformNormalNodeMsl : public TransformVectorNodeMsl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- const string& getMatrix(const string& fromSpace, const string& toSpace) const override;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp
deleted file mode 100644
index 38db776855..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.cpp
+++ /dev/null
@@ -1,23 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformPointNodeMsl::create()
-{
- return std::make_shared();
-}
-
-string TransformPointNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const
-{
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- return "float4(" + shadergen.getUpstreamResult(in, context) + ", 1.0)";
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h
deleted file mode 100644
index 9fc2361d7d..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformPointNodeMsl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMPOINTNODEMSL_H
-#define MATERIALX_TRANSFORMPOINTNODEMSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformPoint node implementation for MSL
-class MX_GENMSL_API TransformPointNodeMsl : public TransformVectorNodeMsl
-{
- public:
- static ShaderNodeImplPtr create();
-
- protected:
- virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const override;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp
deleted file mode 100644
index c5d6ce242a..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.cpp
+++ /dev/null
@@ -1,84 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#include
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-ShaderNodeImplPtr TransformVectorNodeMsl::create()
-{
- return std::make_shared();
-}
-
-void TransformVectorNodeMsl::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
-{
- const ShaderInput* toSpaceInput = node.getInput(TO_SPACE);
- string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE);
- string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const string& matrix = getMatrix(fromSpace, toSpace);
- if (!matrix.empty())
- {
- ShaderStage& ps = shader.getStage(Stage::PIXEL);
- addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps);
- }
-}
-
-void TransformVectorNodeMsl::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
-{
- DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
- {
- const ShaderGenerator& shadergen = context.getShaderGenerator();
-
- const ShaderInput* inInput = node.getInput("in");
- if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4)
- {
- throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4.");
- }
-
- const ShaderInput* toSpaceInput = node.getInput(TO_SPACE);
- string toSpace = toSpaceInput ? toSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- const ShaderInput* fromSpaceInput = node.getInput(FROM_SPACE);
- string fromSpace = fromSpaceInput ? fromSpaceInput->getValue()->getValueString() : EMPTY_STRING;
-
- shadergen.emitLineBegin(stage);
- shadergen.emitOutput(node.getOutput(), true, false, context, stage);
- shadergen.emitString(" = (", stage);
- const string& matrix = getMatrix(fromSpace, toSpace);
- if (!matrix.empty())
- {
- shadergen.emitString(matrix + " * ", stage);
- }
- shadergen.emitString(getHomogeneousCoordinate(inInput, context), stage);
- shadergen.emitString(").xyz", stage);
- shadergen.emitLineEnd(stage);
- }
-}
-
-const string& TransformVectorNodeMsl::getMatrix(const string& fromSpace, const string& toSpace) const
-{
- if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD)
- {
- return HW::T_WORLD_MATRIX;
- }
- else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT))
- {
- return HW::T_WORLD_INVERSE_MATRIX;
- }
- return EMPTY_STRING;
-}
-
-string TransformVectorNodeMsl::getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const
-{
- const ShaderGenerator& shadergen = context.getShaderGenerator();
- return "float4(" + shadergen.getUpstreamResult(in, context) + ", 0.0)";
-}
-
-MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h b/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h
deleted file mode 100644
index 013a3db29a..0000000000
--- a/source/MaterialXGenMsl/Nodes/TransformVectorNodeMsl.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//
-// Copyright Contributors to the MaterialX Project
-// SPDX-License-Identifier: Apache-2.0
-//
-
-#ifndef MATERIALX_TRANSFORMVECTORNODEMSL_H
-#define MATERIALX_TRANSFORMVECTORNODEMSL_H
-
-#include
-
-MATERIALX_NAMESPACE_BEGIN
-
-/// TransformVector node implementation for MSL
-class MX_GENMSL_API TransformVectorNodeMsl : public MslImplementation
-{
- public:
- static ShaderNodeImplPtr create();
-
- void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override;
-
- void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
-
- protected:
- virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const;
- virtual string getHomogeneousCoordinate(const ShaderInput* in, GenContext& context) const;
-};
-
-MATERIALX_NAMESPACE_END
-
-#endif
diff --git a/source/MaterialXGenOsl/OslShaderGenerator.cpp b/source/MaterialXGenOsl/OslShaderGenerator.cpp
index 28ada48626..fbb2bb29be 100644
--- a/source/MaterialXGenOsl/OslShaderGenerator.cpp
+++ b/source/MaterialXGenOsl/OslShaderGenerator.cpp
@@ -294,6 +294,25 @@ ShaderPtr OslShaderGenerator::generate(const string& name, ElementPtr element, G
emitLineBreak(stage);
}
+ // Inputs of type 'filename' has been generated into two shader inputs.
+ // So here we construct a single 'textureresource' from these inputs,
+ // to be used further downstream. See emitShaderInputs() for details.
+ VariableBlock& inputs = stage.getUniformBlock(OSL::UNIFORMS);
+ for (size_t i = 0; i < inputs.size(); ++i)
+ {
+ ShaderPort* input = inputs[i];
+ if (input->getType() == Type::FILENAME)
+ {
+ // Construct the textureresource variable.
+ const string newVariableName = input->getVariable() + "_";
+ const string& type = _syntax->getTypeName(input->getType());
+ emitLine(type + newVariableName + " = {" + input->getVariable() + ", " + input->getVariable() + "_colorspace}", stage);
+
+ // Update the variable name to be used downstream.
+ input->setVariable(newVariableName);
+ }
+ }
+
// Emit all texturing nodes. These are inputs to any
// closure/shader nodes and need to be emitted first.
emitFunctionCalls(graph, context, stage, ShaderNode::Classification::TEXTURE);
@@ -489,111 +508,75 @@ void OslShaderGenerator::emitLibraryIncludes(ShaderStage& stage, GenContext& con
emitLineBreak(stage);
}
-namespace
-{
-
-std::unordered_map GEOMPROP_DEFINITIONS =
-{
- { "Pobject", "transform(\"object\", P)" },
- { "Pworld", "P" },
- { "Nobject", "transform(\"object\", N)" },
- { "Nworld", "N" },
- { "Tobject", "transform(\"object\", dPdu)" },
- { "Tworld", "dPdu" },
- { "Bobject", "transform(\"object\", dPdv)" },
- { "Bworld", "dPdv" },
- { "UV0", "{u,v}" },
- { "Vworld", "I" }
-};
-
-} // anonymous namespace
-
void OslShaderGenerator::emitShaderInputs(const VariableBlock& inputs, ShaderStage& stage) const
{
- const std::unordered_map UI_WIDGET_METADATA =
- {
- { Type::FLOAT, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) },
- { Type::INTEGER, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) },
- { Type::FILENAME, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("filename", Type::STRING->getName())) },
- { Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("checkBox", Type::STRING->getName())) }
- };
-
- const std::set METADATA_TYPE_BLACKLIST =
+ static const std::unordered_map GEOMPROP_DEFINITIONS =
{
- Type::VECTOR2, // Custom struct types doesn't support metadata declarations.
- Type::VECTOR4, //
- Type::COLOR4, //
- Type::FILENAME, //
- Type::BSDF //
+ { "Pobject", "transform(\"object\", P)" },
+ { "Pworld", "P" },
+ { "Nobject", "transform(\"object\", N)" },
+ { "Nworld", "N" },
+ { "Tobject", "transform(\"object\", dPdu)" },
+ { "Tworld", "dPdu" },
+ { "Bobject", "transform(\"object\", dPdv)" },
+ { "Bworld", "dPdv" },
+ { "UV0", "{u,v}" },
+ { "Vworld", "I" }
};
for (size_t i = 0; i < inputs.size(); ++i)
{
const ShaderPort* input = inputs[i];
-
const string& type = _syntax->getTypeName(input->getType());
- string value = _syntax->getValue(input, true);
-
- emitLineBegin(stage);
- emitString(type + " " + input->getVariable(), stage);
- const string& geomprop = input->getGeomProp();
- if (!geomprop.empty())
+ if (input->getType() == Type::FILENAME)
{
- auto it = GEOMPROP_DEFINITIONS.find(geomprop);
- if (it != GEOMPROP_DEFINITIONS.end())
- {
- value = it->second;
- }
+ // Shader inputs of type 'filename' (textures) need special handling.
+ // In OSL codegen a 'filename' is translated to the custom type 'textureresource',
+ // which is a struct containing a file string and a colorspace string.
+ // For the published shader interface we here split this into two separate inputs,
+ // which gives a nicer shader interface with widget metadata on each input.
+
+ ValuePtr value = input->getValue();
+ const string valueStr = value ? value->getValueString() : EMPTY_STRING;
+
+ // Add the file string input
+ emitLineBegin(stage);
+ emitString("string " + input->getVariable() + " = \"" + valueStr + "\"", stage);
+ emitMetadata(input, stage);
+ emitString(",", stage);
+ emitLineEnd(stage, false);
+
+ // Add the colorspace string input
+ emitLineBegin(stage);
+ emitString("string " + input->getVariable() + "_colorspace = \"" + input->getColorSpace() + "\"", stage);
+ emitLineEnd(stage, false);
+ emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS);
+ emitLine("string widget = \"colorspace\"", stage, false);
+ emitScopeEnd(stage, false, false);
}
-
- if (value.empty())
+ else
{
- value = _syntax->getDefaultValue(input->getType());
- }
- emitString(" = " + value, stage);
-
- //
- // Add shader input metadata.
- //
-
- auto widgetMetadataIt = UI_WIDGET_METADATA.find(input->getType());
- const ShaderMetadata* widgetMetadata = widgetMetadataIt != UI_WIDGET_METADATA.end() ? &widgetMetadataIt->second : nullptr;
- const ShaderMetadataVecPtr& metadata = input->getMetadata();
+ emitLineBegin(stage);
+ emitString(type + " " + input->getVariable(), stage);
- if (widgetMetadata || (metadata && metadata->size()))
- {
- StringVec metadataLines;
- if (metadata)
+ string value = _syntax->getValue(input, true);
+ const string& geomprop = input->getGeomProp();
+ if (!geomprop.empty())
{
- for (size_t j = 0; j < metadata->size(); ++j)
+ auto it = GEOMPROP_DEFINITIONS.find(geomprop);
+ if (it != GEOMPROP_DEFINITIONS.end())
{
- const ShaderMetadata& data = metadata->at(j);
- if (METADATA_TYPE_BLACKLIST.count(data.type) == 0)
- {
- const string& delim = (widgetMetadata || j < metadata->size() - 1) ? Syntax::COMMA : EMPTY_STRING;
- const string& dataType = _syntax->getTypeName(data.type);
- const string dataValue = _syntax->getValue(data.type, *data.value, true);
- metadataLines.push_back(dataType + " " + data.name + " = " + dataValue + delim);
- }
+ value = it->second;
}
}
- if (widgetMetadata)
+ if (value.empty())
{
- const string& dataType = _syntax->getTypeName(widgetMetadata->type);
- const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, true);
- metadataLines.push_back(dataType + " " + widgetMetadata->name + " = " + dataValue);
- }
- if (metadataLines.size())
- {
- emitLineEnd(stage, false);
- emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS);
- for (auto line : metadataLines)
- {
- emitLine(line, stage, false);
- }
- emitScopeEnd(stage, false, false);
+ value = _syntax->getDefaultValue(input->getType());
}
+
+ emitString(" = " + value, stage);
+ emitMetadata(input, stage);
}
if (i < inputs.size())
@@ -618,6 +601,65 @@ void OslShaderGenerator::emitShaderOutputs(const VariableBlock& outputs, ShaderS
}
}
+void OslShaderGenerator::emitMetadata(const ShaderPort* port, ShaderStage& stage) const
+{
+ static const std::unordered_map UI_WIDGET_METADATA =
+ {
+ { Type::FLOAT, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) },
+ { Type::INTEGER, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("number", Type::STRING->getName())) },
+ { Type::FILENAME, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("filename", Type::STRING->getName())) },
+ { Type::BOOLEAN, ShaderMetadata("widget", Type::STRING, Value::createValueFromStrings("checkBox", Type::STRING->getName())) }
+ };
+
+ static const std::set METADATA_TYPE_BLACKLIST =
+ {
+ Type::VECTOR2, // Custom struct types doesn't support metadata declarations.
+ Type::VECTOR4, //
+ Type::COLOR4, //
+ Type::FILENAME, //
+ Type::BSDF //
+ };
+
+ auto widgetMetadataIt = UI_WIDGET_METADATA.find(port->getType());
+ const ShaderMetadata* widgetMetadata = widgetMetadataIt != UI_WIDGET_METADATA.end() ? &widgetMetadataIt->second : nullptr;
+ const ShaderMetadataVecPtr& metadata = port->getMetadata();
+
+ if (widgetMetadata || (metadata && metadata->size()))
+ {
+ StringVec metadataLines;
+ if (metadata)
+ {
+ for (size_t j = 0; j < metadata->size(); ++j)
+ {
+ const ShaderMetadata& data = metadata->at(j);
+ if (METADATA_TYPE_BLACKLIST.count(data.type) == 0)
+ {
+ const string& delim = (widgetMetadata || j < metadata->size() - 1) ? Syntax::COMMA : EMPTY_STRING;
+ const string& dataType = _syntax->getTypeName(data.type);
+ const string dataValue = _syntax->getValue(data.type, *data.value, true);
+ metadataLines.push_back(dataType + " " + data.name + " = " + dataValue + delim);
+ }
+ }
+ }
+ if (widgetMetadata)
+ {
+ const string& dataType = _syntax->getTypeName(widgetMetadata->type);
+ const string dataValue = _syntax->getValue(widgetMetadata->type, *widgetMetadata->value, true);
+ metadataLines.push_back(dataType + " " + widgetMetadata->name + " = " + dataValue);
+ }
+ if (metadataLines.size())
+ {
+ emitLineEnd(stage, false);
+ emitScopeBegin(stage, Syntax::DOUBLE_SQUARE_BRACKETS);
+ for (auto line : metadataLines)
+ {
+ emitLine(line, stage, false);
+ }
+ emitScopeEnd(stage, false, false);
+ }
+ }
+}
+
namespace OSL
{
diff --git a/source/MaterialXGenOsl/OslShaderGenerator.h b/source/MaterialXGenOsl/OslShaderGenerator.h
index 0c7ca426d7..e5cf13977e 100644
--- a/source/MaterialXGenOsl/OslShaderGenerator.h
+++ b/source/MaterialXGenOsl/OslShaderGenerator.h
@@ -59,6 +59,9 @@ class MX_GENOSL_API OslShaderGenerator : public ShaderGenerator
/// Emit a block of shader outputs.
virtual void emitShaderOutputs(const VariableBlock& inputs, ShaderStage& stage) const;
+
+ /// Emit metadata for a shader parameter.
+ virtual void emitMetadata(const ShaderPort* port, ShaderStage& stage) const;
};
namespace OSL
diff --git a/source/MaterialXGenShader/HwShaderGenerator.h b/source/MaterialXGenShader/HwShaderGenerator.h
index 66d60dc68a..bba572c631 100644
--- a/source/MaterialXGenShader/HwShaderGenerator.h
+++ b/source/MaterialXGenShader/HwShaderGenerator.h
@@ -306,6 +306,9 @@ class MX_GENSHADER_API HwShaderGenerator : public ShaderGenerator
/// Unbind all light shaders previously bound.
static void unbindLightShaders(GenContext& context);
+ /// Determine the prefix of vertex data variables.
+ virtual string getVertexDataPrefix(const VariableBlock& vertexData) const = 0;
+
/// Types of closure contexts for HW.
enum ClosureContextType
{
diff --git a/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp b/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp
new file mode 100644
index 0000000000..3aa84400df
--- /dev/null
+++ b/source/MaterialXGenShader/Nodes/HwTexCoordNode.cpp
@@ -0,0 +1,83 @@
+//
+// Copyright Contributors to the MaterialX Project
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include
+#include
+#include
+
+MATERIALX_NAMESPACE_BEGIN
+
+string HwTexCoordNode::INDEX = "index";
+
+ShaderNodeImplPtr HwTexCoordNode::create()
+{
+ return std::make_shared();
+}
+
+void HwTexCoordNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
+{
+ const ShaderOutput* output = node.getOutput();
+ const string index = getIndex(node);
+
+ ShaderStage& vs = shader.getStage(Stage::VERTEX);
+ ShaderStage& ps = shader.getStage(Stage::PIXEL);
+
+ addStageInput(HW::VERTEX_INPUTS, output->getType(), HW::T_IN_TEXCOORD + "_" + index, vs, true);
+ addStageConnector(HW::VERTEX_DATA, output->getType(), HW::T_TEXCOORD + "_" + index, vs, ps, true);
+}
+
+void HwTexCoordNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
+{
+ const HwShaderGenerator& shadergen = static_cast(context.getShaderGenerator());
+
+ const string index = getIndex(node);
+ const string variable = HW::T_TEXCOORD + "_" + index;
+ const ShaderOutput* output = node.getOutput();
+
+ DEFINE_SHADER_STAGE(stage, Stage::VERTEX)
+ {
+ VariableBlock& vertexData = stage.getOutputBlock(HW::VERTEX_DATA);
+ const string prefix = shadergen.getVertexDataPrefix(vertexData);
+ ShaderPort* texcoord = vertexData[variable];
+ if (!texcoord->isEmitted())
+ {
+ shadergen.emitLine(prefix + texcoord->getVariable() + " = " + HW::T_IN_TEXCOORD + "_" + index, stage);
+ texcoord->setEmitted();
+ }
+ }
+
+ DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
+ {
+ VariableBlock& vertexData = stage.getInputBlock(HW::VERTEX_DATA);
+ const string prefix = shadergen.getVertexDataPrefix(vertexData);
+ ShaderPort* texcoord = vertexData[variable];
+ shadergen.emitLineBegin(stage);
+ shadergen.emitOutput(output, true, false, context, stage);
+
+ // Extract the requested number of components from the texture coordinates (which may be a
+ // larger datatype than the requested number of texture coordinates, if several texture
+ // coordinate nodes with different width coexist).
+ string suffix = EMPTY_STRING;
+ if (output->getType() == Type::VECTOR2)
+ {
+ suffix = ".xy";
+ }
+ else if (output->getType() == Type::VECTOR3)
+ {
+ suffix = ".xyz";
+ }
+
+ shadergen.emitString(" = " + prefix + texcoord->getVariable() + suffix, stage);
+ shadergen.emitLineEnd(stage);
+ }
+}
+
+string HwTexCoordNode::getIndex(const ShaderNode& node) const
+{
+ const ShaderInput* input = node.getInput(INDEX);
+ return input ? input->getValue()->getValueString() : "0";
+}
+
+MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h b/source/MaterialXGenShader/Nodes/HwTexCoordNode.h
similarity index 55%
rename from source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h
rename to source/MaterialXGenShader/Nodes/HwTexCoordNode.h
index c15a86fd9c..9aae3d18ce 100644
--- a/source/MaterialXGenGlsl/Nodes/TexCoordNodeGlsl.h
+++ b/source/MaterialXGenShader/Nodes/HwTexCoordNode.h
@@ -3,15 +3,15 @@
// SPDX-License-Identifier: Apache-2.0
//
-#ifndef MATERIALX_TEXCOORDNODEGLSL_H
-#define MATERIALX_TEXCOORDNODEGLSL_H
+#ifndef MATERIALX_HWTEXCOORDNODE_H
+#define MATERIALX_HWTEXCOORDNODE_H
-#include
+#include
MATERIALX_NAMESPACE_BEGIN
-/// TexCoord node implementation for GLSL
-class MX_GENGLSL_API TexCoordNodeGlsl : public GlslImplementation
+/// Generic texture coordinate node for hardware languages
+class MX_GENSHADER_API HwTexCoordNode : public ShaderNodeImpl
{
public:
static ShaderNodeImplPtr create();
@@ -19,6 +19,11 @@ class MX_GENGLSL_API TexCoordNodeGlsl : public GlslImplementation
void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override;
void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
+
+ protected:
+ virtual string getIndex(const ShaderNode& node) const;
+
+ static string INDEX;
};
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.cpp b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp
new file mode 100644
index 0000000000..018924855d
--- /dev/null
+++ b/source/MaterialXGenShader/Nodes/HwTransformNode.cpp
@@ -0,0 +1,110 @@
+//
+// Copyright Contributors to the MaterialX Project
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#include
+#include
+#include
+
+MATERIALX_NAMESPACE_BEGIN
+
+const string HwTransformNode::FROM_SPACE = "fromspace";
+const string HwTransformNode::TO_SPACE = "tospace";
+const string HwTransformNode::MODEL = "model";
+const string HwTransformNode::OBJECT = "object";
+const string HwTransformNode::WORLD = "world";
+
+void HwTransformNode::createVariables(const ShaderNode& node, GenContext&, Shader& shader) const
+{
+ const string toSpace = getToSpace(node);
+ const string fromSpace = getFromSpace(node);
+ const string& matrix = getMatrix(fromSpace, toSpace);
+ if (!matrix.empty())
+ {
+ ShaderStage& ps = shader.getStage(Stage::PIXEL);
+ addStageUniform(HW::PRIVATE_UNIFORMS, Type::MATRIX44, matrix, ps);
+ }
+}
+
+void HwTransformNode::emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const
+{
+ DEFINE_SHADER_STAGE(stage, Stage::PIXEL)
+ {
+ const ShaderGenerator& shadergen = context.getShaderGenerator();
+
+ const ShaderOutput* output = node.getOutput();
+ const ShaderInput* inInput = node.getInput("in");
+ if (inInput->getType() != Type::VECTOR3 && inInput->getType() != Type::VECTOR4)
+ {
+ throw ExceptionShaderGenError("Transform node must have 'in' type of vector3 or vector4.");
+ }
+
+ shadergen.emitLineBegin(stage);
+ shadergen.emitOutput(output, true, false, context, stage);
+ shadergen.emitString(" = (", stage);
+
+ const string toSpace = getToSpace(node);
+ const string fromSpace = getFromSpace(node);
+ const string& matrix = getMatrix(fromSpace, toSpace);
+ if (!matrix.empty())
+ {
+ shadergen.emitString(matrix + " * ", stage);
+ }
+
+ const string type = shadergen.getSyntax().getTypeName(Type::VECTOR4);
+ const string input = shadergen.getUpstreamResult(inInput, context);
+ shadergen.emitString(type + "(" + input + ", " + getHomogeneousCoordinate() + ")).xyz", stage);
+ shadergen.emitLineEnd(stage);
+
+ if (shouldNormalize())
+ {
+ shadergen.emitLineBegin(stage);
+ shadergen.emitOutput(output, false, false, context, stage);
+ shadergen.emitString(" = normalize(" + output->getVariable() + ")", stage);
+ shadergen.emitLineEnd(stage);
+ }
+ }
+}
+
+string HwTransformNode::getFromSpace(const ShaderNode& node) const
+{
+ const ShaderInput* input = node.getInput(FROM_SPACE);
+ return input ? input->getValueString() : EMPTY_STRING;
+}
+
+string HwTransformNode::getToSpace(const ShaderNode& node) const
+{
+ const ShaderInput* input = node.getInput(TO_SPACE);
+ return input ? input->getValueString() : EMPTY_STRING;
+}
+
+const string& HwTransformNode::getMatrix(const string& fromSpace, const string& toSpace) const
+{
+ if ((fromSpace == MODEL || fromSpace == OBJECT) && toSpace == WORLD)
+ {
+ return getModelToWorldMatrix();
+ }
+ else if (fromSpace == WORLD && (toSpace == MODEL || toSpace == OBJECT))
+ {
+ return getWorldToModelMatrix();
+ }
+ return EMPTY_STRING;
+}
+
+ShaderNodeImplPtr HwTransformVectorNode::create()
+{
+ return std::make_shared();
+}
+
+ShaderNodeImplPtr HwTransformPointNode::create()
+{
+ return std::make_shared();
+}
+
+ShaderNodeImplPtr HwTransformNormalNode::create()
+{
+ return std::make_shared();
+}
+
+MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGenShader/Nodes/HwTransformNode.h b/source/MaterialXGenShader/Nodes/HwTransformNode.h
new file mode 100644
index 0000000000..a97e57405c
--- /dev/null
+++ b/source/MaterialXGenShader/Nodes/HwTransformNode.h
@@ -0,0 +1,71 @@
+//
+// Copyright Contributors to the MaterialX Project
+// SPDX-License-Identifier: Apache-2.0
+//
+
+#ifndef MATERIALX_HWTRANSFORMNODE_H
+#define MATERIALX_HWTRANSFORMNODE_H
+
+#include
+
+MATERIALX_NAMESPACE_BEGIN
+
+/// Generic transformation node for hardware languages
+class MX_GENSHADER_API HwTransformNode : public ShaderNodeImpl
+{
+ public:
+ void createVariables(const ShaderNode& node, GenContext& context, Shader& shader) const override;
+ void emitFunctionCall(const ShaderNode& node, GenContext& context, ShaderStage& stage) const override;
+
+ protected:
+ virtual const string& getMatrix(const string& fromSpace, const string& toSpace) const;
+ virtual const string& getModelToWorldMatrix() const = 0;
+ virtual const string& getWorldToModelMatrix() const = 0;
+ virtual string getHomogeneousCoordinate() const = 0;
+ virtual bool shouldNormalize() const { return false; }
+
+ virtual string getFromSpace(const ShaderNode&) const;
+ virtual string getToSpace(const ShaderNode&) const;
+
+ static const string FROM_SPACE;
+ static const string TO_SPACE;
+ static const string MODEL;
+ static const string OBJECT;
+ static const string WORLD;
+};
+
+class MX_GENSHADER_API HwTransformVectorNode : public HwTransformNode
+{
+ public:
+ static ShaderNodeImplPtr create();
+
+ protected:
+ const string& getModelToWorldMatrix() const override { return HW::T_WORLD_MATRIX; }
+ const string& getWorldToModelMatrix() const override { return HW::T_WORLD_INVERSE_MATRIX; }
+ string getHomogeneousCoordinate() const override { return "0.0"; }
+};
+
+class MX_GENSHADER_API HwTransformPointNode : public HwTransformVectorNode
+{
+ public:
+ static ShaderNodeImplPtr create();
+
+ protected:
+ string getHomogeneousCoordinate() const override { return "1.0"; }
+};
+
+class MX_GENSHADER_API HwTransformNormalNode : public HwTransformNode
+{
+ public:
+ static ShaderNodeImplPtr create();
+
+ protected:
+ const string& getModelToWorldMatrix() const override { return HW::T_WORLD_INVERSE_TRANSPOSE_MATRIX; }
+ const string& getWorldToModelMatrix() const override { return HW::T_WORLD_TRANSPOSE_MATRIX; }
+ string getHomogeneousCoordinate() const override { return "0.0"; }
+ bool shouldNormalize() const override { return true; }
+};
+
+MATERIALX_NAMESPACE_END
+
+#endif
diff --git a/source/MaterialXGenShader/ShaderNode.cpp b/source/MaterialXGenShader/ShaderNode.cpp
index 04551cb6d2..3e393178f1 100644
--- a/source/MaterialXGenShader/ShaderNode.cpp
+++ b/source/MaterialXGenShader/ShaderNode.cpp
@@ -32,6 +32,11 @@ string ShaderPort::getFullName() const
return (_node->getName() + "_" + _name);
}
+string ShaderPort::getValueString() const
+{
+ return getValue() ? getValue()->getValueString() : EMPTY_STRING;
+}
+
//
// ShaderInput methods
//
diff --git a/source/MaterialXGenShader/ShaderNode.h b/source/MaterialXGenShader/ShaderNode.h
index 536e0adc1e..dd74269764 100644
--- a/source/MaterialXGenShader/ShaderNode.h
+++ b/source/MaterialXGenShader/ShaderNode.h
@@ -170,6 +170,9 @@ class MX_GENSHADER_API ShaderPort : public std::enable_shared_from_thissecond->getType()->getSize() < type->getSize())
+ {
+ it->second->setType(type);
+ }
+ }
+ else if (type != it->second->getType())
+ {
+ throw ExceptionShaderGenError("Trying to add shader port '" + name + "' with type '" +
+ type->getName() + "', but existing shader port with type '" +
+ it->second->getType()->getName() + "' was found");
+ }
return it->second.get();
}
diff --git a/source/MaterialXGenShader/ShaderStage.h b/source/MaterialXGenShader/ShaderStage.h
index 71004f8e52..a6a5cec0b8 100644
--- a/source/MaterialXGenShader/ShaderStage.h
+++ b/source/MaterialXGenShader/ShaderStage.h
@@ -113,7 +113,14 @@ class MX_GENSHADER_API VariableBlock
ShaderPort* find(const ShaderPortPredicate& predicate);
/// Add a new shader port to this block.
- ShaderPort* add(const TypeDesc* type, const string& name, ValuePtr value = nullptr);
+ /// @param type The desired shader port type
+ /// @param name The shader port name
+ /// @param value The value to attach to the shader port
+ /// @param shouldWiden When false, an exception is thrown if the type of the existing port with
+ /// the same name does not match the requested type. When true, the types can mismatch, and the
+ /// type of any existing port is widened to match the requested type when necessary.
+ /// @return A new shader port, or a pre-existing shader port with the same name.
+ ShaderPort* add(const TypeDesc* type, const string& name, ValuePtr value = nullptr, bool shouldWiden = false);
/// Add an existing shader port to this block.
void add(ShaderPortPtr port);
@@ -339,20 +346,22 @@ inline ShaderPort* addStageUniform(const string& block,
inline ShaderPort* addStageInput(const string& block,
const TypeDesc* type,
const string& name,
- ShaderStage& stage)
+ ShaderStage& stage,
+ bool shouldWiden = false)
{
VariableBlock& inputs = stage.getInputBlock(block);
- return inputs.add(type, name);
+ return inputs.add(type, name, {}, shouldWiden);
}
/// Utility function for adding a new shader port to an output block.
inline ShaderPort* addStageOutput(const string& block,
const TypeDesc* type,
const string& name,
- ShaderStage& stage)
+ ShaderStage& stage,
+ bool shouldWiden = false)
{
VariableBlock& outputs = stage.getOutputBlock(block);
- return outputs.add(type, name);
+ return outputs.add(type, name, {}, shouldWiden);
}
/// Utility function for adding a connector block between stages.
@@ -370,10 +379,11 @@ inline void addStageConnector(const string& block,
const TypeDesc* type,
const string& name,
ShaderStage& from,
- ShaderStage& to)
+ ShaderStage& to,
+ bool shouldWiden = false)
{
- addStageOutput(block, type, name, from);
- addStageInput(block, type, name, to);
+ addStageOutput(block, type, name, from, shouldWiden);
+ addStageInput(block, type, name, to, shouldWiden);
}
MATERIALX_NAMESPACE_END
diff --git a/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt b/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt
index eaae85a825..2ec553856f 100644
--- a/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt
+++ b/source/MaterialXGraphEditor/External/Glfw/CMakeLists.txt
@@ -41,7 +41,7 @@ if (BUILD_SHARED_LIBS AND UNIX)
# On Unix-like systems, shared libraries can use the soname system.
set(GLFW_LIB_NAME glfw)
else()
- set(GLFW_LIB_NAME glfw3)
+ set(GLFW_LIB_NAME glfw3_minimal)
endif()
if (GLFW_VULKAN_STATIC)
diff --git a/source/MaterialXGraphEditor/Graph.cpp b/source/MaterialXGraphEditor/Graph.cpp
index 2b28317ee2..849b8607b4 100644
--- a/source/MaterialXGraphEditor/Graph.cpp
+++ b/source/MaterialXGraphEditor/Graph.cpp
@@ -236,9 +236,6 @@ void Graph::addExtraNodes()
return;
}
- // Clear any old nodes, if we previously used tab with another graph doc
- _extraNodes.clear();
-
// Get all types from the doc
std::vector types;
std::vector typeDefs = _graphDoc->getTypeDefs();
@@ -252,18 +249,16 @@ void Graph::addExtraNodes()
for (const std::string& type : types)
{
std::string nodeName = "ND_input_" + type;
- _extraNodes["Input Nodes"].push_back({ nodeName, type, "input" });
+ _nodesToAdd.emplace_back(nodeName, type, "input", "Input Nodes");
nodeName = "ND_output_" + type;
- _extraNodes["Output Nodes"].push_back({ nodeName, type, "output" });
+ _nodesToAdd.emplace_back(nodeName, type, "output", "Output Nodes");
}
// Add group node
- std::vector groupNode{ "ND_group", "", "group" };
- _extraNodes["Group Nodes"].push_back(groupNode);
+ _nodesToAdd.emplace_back("ND_group", "", "group", "Group Nodes");
// Add nodegraph node
- std::vector nodeGraph{ "ND_nodegraph", "", "nodegraph" };
- _extraNodes["Node Graph"].push_back(nodeGraph);
+ _nodesToAdd.emplace_back("ND_nodegraph", "", "nodegraph", "Node Graph");
}
ed::PinId Graph::getOutputPin(UiNodePtr node, UiNodePtr upNode, UiPinPtr input)
@@ -846,7 +841,7 @@ void Graph::setRenderMaterial(UiNodePtr node)
}
}
-void Graph::updateMaterials(mx::InputPtr input, mx::ValuePtr value)
+void Graph::updateMaterials(mx::InputPtr input /* = nullptr */, mx::ValuePtr value /* = nullptr */)
{
std::string renderablePath;
if (_currRenderNode)
@@ -1224,20 +1219,63 @@ void Graph::setUiNodeInfo(UiNodePtr node, const std::string& type, const std::st
void Graph::createNodeUIList(mx::DocumentPtr doc)
{
_nodesToAdd.clear();
- const std::string EXTRA_GROUP_NAME = "extra";
- for (mx::NodeDefPtr nodeDef : doc->getNodeDefs())
+
+ std::vector ordered_groups = {
+ "texture2d",
+ "texture3d",
+ "procedural",
+ "procedural2d",
+ "procedural3d",
+ "geometric",
+ "translation",
+ "convolution2d",
+ "math",
+ "adjustment",
+ "compositing",
+ "conditional",
+ "channel",
+ "organization",
+ "global",
+ "application",
+ "material",
+ "shader",
+ "pbr",
+ "light",
+ "colortransform",
+ "no_group"
+ };
+
+ auto nodeDefs = doc->getNodeDefs();
+ std::unordered_map> groupToNodeDef;
+
+ for (const auto& nodeDef : nodeDefs)
{
- // NodeDef is the key for the map
std::string group = nodeDef->getNodeGroup();
+
if (group.empty())
{
- group = EXTRA_GROUP_NAME;
+ group = "no_group";
}
- if (_nodesToAdd.find(group) == _nodesToAdd.end())
+
+ if (groupToNodeDef.find(group) == groupToNodeDef.end())
+ {
+ groupToNodeDef[group] = std::vector();
+ }
+ groupToNodeDef[group].push_back(nodeDef);
+ }
+
+ for (const auto& group : ordered_groups)
+ {
+ auto it = groupToNodeDef.find(group);
+ if (it != groupToNodeDef.end())
{
- _nodesToAdd[group] = std::vector();
+ const auto& groupNodeDefs = it->second;
+
+ for (const auto& nodeDef : groupNodeDefs)
+ {
+ _nodesToAdd.emplace_back(nodeDef->getName(), nodeDef->getType(), nodeDef->getNodeString(), group);
+ }
}
- _nodesToAdd[group].push_back(nodeDef);
}
addExtraNodes();
@@ -2483,12 +2521,22 @@ void Graph::setDefaults(mx::InputPtr input)
}
}
-void Graph::addLink(ed::PinId inputPinId, ed::PinId outputPinId)
+void Graph::addLink(ed::PinId startPinId, ed::PinId endPinId)
{
- int end_attr = int(outputPinId.Get());
- int start_attr = int(inputPinId.Get());
- UiPinPtr inputPin = getPin(outputPinId);
- UiPinPtr outputPin = getPin(inputPinId);
+ // prefer to assume left to right - start is an output, end is an input; swap if inaccurate
+ if (UiPinPtr inputPin = getPin(endPinId); inputPin && inputPin->_kind != ed::PinKind::Input)
+ {
+ auto tmp = startPinId;
+ startPinId = endPinId;
+ endPinId = tmp;
+ }
+
+ int end_attr = int(endPinId.Get());
+ int start_attr = int(startPinId.Get());
+ ed::PinId outputPinId = startPinId;
+ ed::PinId inputPinId = endPinId;
+ UiPinPtr outputPin = getPin(outputPinId);
+ UiPinPtr inputPin = getPin(inputPinId);
if (!inputPin || !outputPin)
{
@@ -2505,187 +2553,206 @@ void Graph::addLink(ed::PinId inputPinId, ed::PinId outputPinId)
return;
}
- if (inputPin->_connected == false)
+ // Perform kind check
+ bool kindsMatch = (outputPin->_kind == inputPin->_kind);
+ if (kindsMatch)
{
- int upNode = getNodeId(inputPinId);
- int downNode = getNodeId(outputPinId);
- UiNodePtr uiDownNode = _graphNodes[downNode];
- UiNodePtr uiUpNode = _graphNodes[upNode];
- if (!uiDownNode || !uiUpNode)
- {
- ed::RejectNewItem();
- return;
- }
+ ed::RejectNewItem();
+ showLabel("Invalid connection due to same input/output kind", ImColor(50, 50, 50, 255));
+ return;
+ }
- // make sure there is an implementation for node
- const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator();
+ int upNode = getNodeId(outputPinId);
+ int downNode = getNodeId(inputPinId);
+ UiNodePtr uiDownNode = _graphNodes[downNode];
+ UiNodePtr uiUpNode = _graphNodes[upNode];
+ if (!uiDownNode || !uiUpNode)
+ {
+ ed::RejectNewItem();
+ return;
+ }
- // Prevent direct connecting from input to output
- if (uiDownNode->getInput() && uiUpNode->getOutput())
- {
- ed::RejectNewItem();
- showLabel("Direct connections between inputs and outputs is invalid", ImColor(50, 50, 50, 255));
- return;
- }
+ // make sure there is an implementation for node
+ const mx::ShaderGenerator& shadergen = _renderer->getGenContext().getShaderGenerator();
+
+ // Prevent direct connecting from input to output
+ if (uiDownNode->getInput() && uiUpNode->getOutput())
+ {
+ ed::RejectNewItem();
+ showLabel("Direct connections between inputs and outputs is invalid", ImColor(50, 50, 50, 255));
+ return;
+ }
- // Find the implementation for this nodedef if not an input or output uinode
- if (uiDownNode->getInput() && _isNodeGraph)
+ // Find the implementation for this nodedef if not an input or output uinode
+ if (uiDownNode->getInput() && _isNodeGraph)
+ {
+ ed::RejectNewItem();
+ showLabel("Cannot connect to inputs inside of graph", ImColor(50, 50, 50, 255));
+ return;
+ }
+ else if (uiUpNode->getNode())
+ {
+ mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), _renderer->getGenContext());
+ if (!impl)
{
ed::RejectNewItem();
- showLabel("Cannot connect to inputs inside of graph", ImColor(50, 50, 50, 255));
+ showLabel("Invalid Connection: Node does not have an implementation", ImColor(50, 50, 50, 255));
return;
}
- else if (uiUpNode->getNode())
+ }
+
+ if (ed::AcceptNewItem())
+ {
+ // If the accepting node already has a link, remove it
+ if (inputPin->_connected)
{
- mx::ShaderNodeImplPtr impl = shadergen.getImplementation(*_graphNodes[upNode]->getNode()->getNodeDef(), _renderer->getGenContext());
- if (!impl)
+ for (auto linksItr = _currLinks.begin(); linksItr != _currLinks.end(); linksItr++)
{
- ed::RejectNewItem();
- showLabel("Invalid Connection: Node does not have an implementation", ImColor(50, 50, 50, 255));
- return;
+ if (linksItr->_endAttr == end_attr)
+ {
+ // found existing link - remove it; adapted from deleteLink
+ // note: ed::BreakLinks doesn't work as the order ends up inaccurate
+ deleteLinkInfo(linksItr->_startAttr, linksItr->_endAttr);
+ _currLinks.erase(linksItr);
+ break;
+ }
}
+
}
- if (ed::AcceptNewItem())
- {
- // Since we accepted new link, lets add one to our list of links.
- Link link;
- link._startAttr = start_attr;
- link._endAttr = end_attr;
- _currLinks.push_back(link);
- _frameCount = ImGui::GetFrameCount();
- _renderer->setMaterialCompilation(true);
+ // Since we accepted new link, lets add one to our list of links.
+ Link link;
+ link._startAttr = start_attr;
+ link._endAttr = end_attr;
+ _currLinks.push_back(link);
+ _frameCount = ImGui::GetFrameCount();
+ _renderer->setMaterialCompilation(true);
- if (uiDownNode->getNode() || uiDownNode->getNodeGraph())
+ if (uiDownNode->getNode() || uiDownNode->getNodeGraph())
+ {
+ mx::InputPtr connectingInput = nullptr;
+ for (UiPinPtr pin : uiDownNode->inputPins)
{
- mx::InputPtr connectingInput = nullptr;
- for (UiPinPtr pin : uiDownNode->inputPins)
+ if (pin->_pinId == inputPinId)
{
- if (pin->_pinId == outputPinId)
+ addNodeInput(uiDownNode, pin->_input);
+ // update value to be empty
+ if (uiDownNode->getNode() && uiDownNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING)
{
- addNodeInput(uiDownNode, pin->_input);
- // update value to be empty
- if (uiDownNode->getNode() && uiDownNode->getNode()->getType() == mx::SURFACE_SHADER_TYPE_STRING)
+ if (uiUpNode->getOutput() != nullptr)
{
- if (uiUpNode->getOutput() != nullptr)
- {
- pin->_input->setConnectedOutput(uiUpNode->getOutput());
- }
- else if (uiUpNode->getInput() != nullptr)
- {
- pin->_input->setInterfaceName(uiUpNode->getName());
- }
- else
+ pin->_input->setConnectedOutput(uiUpNode->getOutput());
+ }
+ else if (uiUpNode->getInput() != nullptr)
+ {
+ pin->_input->setInterfaceName(uiUpNode->getName());
+ }
+ else
+ {
+ // node graph
+ if (uiUpNode->getNodeGraph() != nullptr)
{
- // node graph
- if (uiUpNode->getNodeGraph() != nullptr)
+ for (UiPinPtr outPin : uiUpNode->outputPins)
{
- for (UiPinPtr outPin : uiUpNode->outputPins)
+ // set pin connection to correct output
+ if (outPin->_pinId == outputPinId)
{
- // set pin connection to correct output
- if (outPin->_pinId == inputPinId)
- {
- mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name);
- pin->_input->setConnectedOutput(outputs);
- }
+ mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name);
+ pin->_input->setConnectedOutput(outputs);
}
}
- else
- {
- pin->_input->setConnectedNode(uiUpNode->getNode());
- }
+ }
+ else
+ {
+ pin->_input->setConnectedNode(uiUpNode->getNode());
}
}
+ }
+ else
+ {
+ if (uiUpNode->getInput())
+ {
+ pin->_input->setInterfaceName(uiUpNode->getName());
+ }
else
{
- if (uiUpNode->getInput())
- {
- pin->_input->setInterfaceName(uiUpNode->getName());
- }
- else
+ if (uiUpNode->getNode())
{
- if (uiUpNode->getNode())
+ mx::NodePtr upstreamNode = _graphNodes[upNode]->getNode();
+ mx::NodeDefPtr upstreamNodeDef = upstreamNode->getNodeDef();
+ bool isMultiOutput = upstreamNodeDef ? upstreamNodeDef->getOutputs().size() > 1 : false;
+
+ // This is purely to avoid adding a reference to an update node only 1 output,
+ // as currently validation consides adding this an error. Otherwise
+ // it will add an "output" attribute all the time.
+ if (!isMultiOutput)
{
- mx::NodePtr upstreamNode = _graphNodes[upNode]->getNode();
- mx::NodeDefPtr upstreamNodeDef = upstreamNode->getNodeDef();
- bool isMultiOutput = upstreamNodeDef ? upstreamNodeDef->getOutputs().size() > 1 : false;
-
- // This is purely to avoid adding a reference to an update node only 1 output,
- // as currently validation consides adding this an error. Otherwise
- // it will add an "output" attribute all the time.
- if (!isMultiOutput)
- {
- pin->_input->setConnectedNode(uiUpNode->getNode());
- }
- else
+ pin->_input->setConnectedNode(uiUpNode->getNode());
+ }
+ else
+ {
+ for (UiPinPtr outPin : _graphNodes[upNode]->outputPins)
{
- for (UiPinPtr outPin : _graphNodes[upNode]->outputPins)
+ // set pin connection to correct output
+ if (outPin->_pinId == outputPinId)
{
- // set pin connection to correct output
- if (outPin->_pinId == inputPinId)
+ mx::OutputPtr outputs = uiUpNode->getNode()->getOutput(outPin->_name);
+ if (!outputs)
{
- mx::OutputPtr outputs = uiUpNode->getNode()->getOutput(outPin->_name);
- if (!outputs)
- {
- outputs = uiUpNode->getNode()->addOutput(outPin->_name, pin->_input->getType());
- }
- pin->_input->setConnectedOutput(outputs);
+ outputs = uiUpNode->getNode()->addOutput(outPin->_name, pin->_input->getType());
}
+ pin->_input->setConnectedOutput(outputs);
}
}
}
- else if (uiUpNode->getNodeGraph())
+ }
+ else if (uiUpNode->getNodeGraph())
+ {
+ for (UiPinPtr outPin : uiUpNode->outputPins)
{
- for (UiPinPtr outPin : uiUpNode->outputPins)
+ // set pin connection to correct output
+ if (outPin->_pinId == outputPinId)
{
- // set pin connection to correct output
- if (outPin->_pinId == inputPinId)
- {
- mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name);
- pin->_input->setConnectedOutput(outputs);
- }
+ mx::OutputPtr outputs = uiUpNode->getNodeGraph()->getOutput(outPin->_name);
+ pin->_input->setConnectedOutput(outputs);
}
}
}
}
-
- pin->setConnected(true);
- pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE);
- connectingInput = pin->_input;
- break;
}
+
+ pin->setConnected(true);
+ pin->_input->removeAttribute(mx::ValueElement::VALUE_ATTRIBUTE);
+ connectingInput = pin->_input;
+ break;
}
- // create new edge and set edge information
- createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput);
}
- else if (_graphNodes[downNode]->getOutput() != nullptr)
- {
- mx::InputPtr connectingInput = nullptr;
- _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode());
+ // create new edge and set edge information
+ createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput);
+ }
+ else if (_graphNodes[downNode]->getOutput() != nullptr)
+ {
+ mx::InputPtr connectingInput = nullptr;
+ _graphNodes[downNode]->getOutput()->setConnectedNode(_graphNodes[upNode]->getNode());
- // create new edge and set edge information
- createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput);
- }
- else
+ // create new edge and set edge information
+ createEdge(_graphNodes[upNode], _graphNodes[downNode], connectingInput);
+ }
+ else
+ {
+ // create new edge and set edge info
+ UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr);
+ if (!edgeExists(newEdge))
{
- // create new edge and set edge info
- UiEdge newEdge = UiEdge(_graphNodes[upNode], _graphNodes[downNode], nullptr);
- if (!edgeExists(newEdge))
- {
- _graphNodes[downNode]->edges.push_back(newEdge);
- _currEdge.push_back(newEdge);
+ _graphNodes[downNode]->edges.push_back(newEdge);
+ _currEdge.push_back(newEdge);
- // update input node num and output connections
- _graphNodes[downNode]->setInputNodeNum(1);
- _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]);
- }
+ // update input node num and output connections
+ _graphNodes[downNode]->setInputNodeNum(1);
+ _graphNodes[upNode]->setOutputConnection(_graphNodes[downNode]);
}
}
}
- else
- {
- ed::RejectNewItem();
- }
}
void Graph::removeEdge(int downNode, int upNode, UiPinPtr pin)
@@ -3566,96 +3633,66 @@ void Graph::addNodePopup(bool cursor)
// Input string length
// Filter extra nodes - includes inputs, outputs, groups, and node graphs
const std::string NODEGRAPH_ENTRY = "Node Graph";
- for (std::unordered_map>>::iterator it = _extraNodes.begin(); it != _extraNodes.end(); ++it)
+
+ // Filter nodedefs and add to menu if matches filter
+ for (auto node : _nodesToAdd)
{
// Filter out list of nodes
if (subs.size() > 0)
{
ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f));
- for (size_t i = 0; i < it->second.size(); i++)
- {
- std::string str(it->second[i][0]);
- std::string nodeName = it->second[i][0];
+ std::string str(node.getName());
+ std::string nodeName = node.getName();
- // Disallow creating nested nodegraphs
- if (_isNodeGraph && it->first == NODEGRAPH_ENTRY)
- {
- continue;
- }
+ // Disallow creating nested nodegraphs
+ if (_isNodeGraph && node.getGroup() == NODEGRAPH_ENTRY)
+ {
+ continue;
+ }
- // Allow spaces to be used to search for node names
- std::replace(subs.begin(), subs.end(), ' ', '_');
+ // Allow spaces to be used to search for node names
+ std::replace(subs.begin(), subs.end(), ' ', '_');
- if (str.find(subs) != std::string::npos)
+ if (str.find(subs) != std::string::npos)
+ {
+ if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
{
- if (ImGui::MenuItem(getUserNodeDefName(nodeName).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
- {
- addNode(it->second[i][2], getUserNodeDefName(nodeName), it->second[i][1]);
- _addNewNode = true;
- memset(input, '\0', sizeof(input));
- }
+ addNode(node.getCategory(), getUserNodeDefName(nodeName), node.getType());
+ _addNewNode = true;
+ memset(input, '\0', sizeof(input));
}
}
}
else
{
ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300));
- if (ImGui::BeginMenu(it->first.c_str()))
+ if (ImGui::BeginMenu(node.getGroup().c_str()))
{
ImGui::SetWindowFontScale(_fontScale);
- for (size_t j = 0; j < it->second.size(); j++)
+ std::string name = node.getName();
+ std::string prefix = "ND_";
+ if (name.compare(0, prefix.size(), prefix) == 0 && name.compare(prefix.size(), std::string::npos, node.getCategory()) == 0)
{
- std::string name = it->second[j][0];
if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
{
- addNode(it->second[j][2], getUserNodeDefName(name), it->second[j][1]);
+ addNode(node.getCategory(), getUserNodeDefName(name), node.getType());
_addNewNode = true;
}
}
- ImGui::EndMenu();
- }
- }
- }
-
- // Filter nodedefs and add to menu if matches filter
- for (std::unordered_map>::iterator it = _nodesToAdd.begin(); it != _nodesToAdd.end(); ++it)
- {
- // Filter out list of nodes
- if (subs.size() > 0)
- {
- ImGui::SetNextWindowSizeConstraints(ImVec2(250.0f, 300.0f), ImVec2(-1.0f, 500.0f));
- for (size_t i = 0; i < it->second.size(); i++)
- {
- std::string str(it->second[i]->getName());
- std::string nodeName = it->second[i]->getName();
- if (str.find(subs) != std::string::npos)
- {
- std::string val = getUserNodeDefName(nodeName);
- if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
- {
- addNode(it->second[i]->getNodeString(), val, it->second[i]->getType());
- _addNewNode = true;
- memset(input, '\0', sizeof(input));
- }
- }
- }
- }
- else
- {
- ImGui::SetNextWindowSizeConstraints(ImVec2(100, 10), ImVec2(-1, 300));
- if (ImGui::BeginMenu(it->first.c_str()))
- {
- ImGui::SetWindowFontScale(_fontScale);
- for (size_t i = 0; i < it->second.size(); i++)
+ else
{
- std::string name = it->second[i]->getName();
- std::string val = getUserNodeDefName(name);
- if (ImGui::MenuItem(val.c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
+ if (ImGui::BeginMenu(node.getCategory().c_str()))
{
- addNode(it->second[i]->getNodeString(), val, it->second[i]->getType());
- _addNewNode = true;
+ if (ImGui::MenuItem(getUserNodeDefName(name).c_str()) || (ImGui::IsItemFocused() && ImGui::IsKeyPressedMap(ImGuiKey_Enter)))
+ {
+ addNode(node.getCategory(), getUserNodeDefName(name), node.getType());
+ _addNewNode = true;
+ }
+ ImGui::EndMenu();
}
}
+
+
ImGui::EndMenu();
}
}
@@ -4045,12 +4082,12 @@ void Graph::drawGraph(ImVec2 mousePos)
// Add new link
if (ed::BeginCreate())
{
- ed::PinId inputPinId, outputPinId, filterPinId;
- if (ed::QueryNewLink(&inputPinId, &outputPinId))
+ ed::PinId startPinId, endPinId, filterPinId;
+ if (ed::QueryNewLink(&startPinId, &endPinId))
{
if (!readOnly())
{
- addLink(inputPinId, outputPinId);
+ addLink(startPinId, endPinId);
}
else
{
diff --git a/source/MaterialXGraphEditor/Graph.h b/source/MaterialXGraphEditor/Graph.h
index 8c76f0f68d..87d4119c2a 100644
--- a/source/MaterialXGraphEditor/Graph.h
+++ b/source/MaterialXGraphEditor/Graph.h
@@ -14,6 +14,30 @@
#include
+class MenuItem
+{
+ public:
+ MenuItem(const std::string& name, const std::string& type, const std::string& category, const std::string& group) :
+ name(name), type(type), category(category), group(group) { }
+
+ // getters
+ std::string getName() const { return name; }
+ std::string getType() const { return type; }
+ std::string getCategory() const { return category; }
+ std::string getGroup() const { return group; }
+
+ // setters
+ void setName(const std::string& newName) { this->name = newName; }
+ void setType(const std::string& newType) { this->type = newType; }
+ void setCategory(const std::string& newCategory) { this->category = newCategory; }
+ void setGroup(const std::string& newGroup) { this->group = newGroup; }
+
+ private:
+ std::string name;
+ std::string type;
+ std::string category;
+ std::string group;
+};
namespace ed = ax::NodeEditor;
namespace mx = MaterialX;
@@ -90,7 +114,9 @@ class Graph
// Add link to nodegraph and set up connections between UiNodes and
// MaterialX Nodes to update shader
- void addLink(ed::PinId inputPinId, ed::PinId outputPinId);
+ // startPinId - where the link was initiated
+ // endPinId - where the link was ended
+ void addLink(ed::PinId startPinId, ed::PinId endPinId);
// Delete link from current link vector and remove any connections in
// UiNode or MaterialX Nodes to update shader
@@ -246,8 +272,7 @@ class Graph
std::vector _currGraphName;
// for adding new nodes
- std::unordered_map> _nodesToAdd;
- std::unordered_map>> _extraNodes;
+ std::vector