diff --git a/resources/Materials/TestSuite/Utilities/closure_color_scene.xml b/resources/Materials/TestSuite/Utilities/closure_color_scene.xml index 9da4591889..a729dbdf46 100644 --- a/resources/Materials/TestSuite/Utilities/closure_color_scene.xml +++ b/resources/Materials/TestSuite/Utilities/closure_color_scene.xml @@ -1,22 +1,21 @@ - - - color Cin %background_color%; - shader constant_color_background layer1; + %environment_shader_parameter_overrides% + shader envmap layer1; + + - - %environment_shader_parameter_overrides% - shader envmap layer1; + color Cin %background_color%; + shader constant_color layer1; - + - + @@ -97,6 +97,13 @@ + + + + + + + diff --git a/source/MaterialXRender/Image.cpp b/source/MaterialXRender/Image.cpp index 4880b22571..115fe3aae5 100644 --- a/source/MaterialXRender/Image.cpp +++ b/source/MaterialXRender/Image.cpp @@ -34,7 +34,7 @@ ImagePtr createUniformImage(unsigned int width, unsigned int height, unsigned in ImagePtr createImageStrip(const vector& imageVec) { - if (imageVec.empty()) + if (imageVec.empty() || !imageVec[0]) { return nullptr; } @@ -53,7 +53,8 @@ ImagePtr createImageStrip(const vector& imageVec) unsigned int xOffset = 0; for (ImagePtr srcImage : imageVec) { - if (srcImage->getWidth() != srcWidth || + if (!srcImage || + srcImage->getWidth() != srcWidth || srcImage->getHeight() != srcHeight || srcImage->getChannelCount() != channelCount || srcImage->getBaseType() != baseType) diff --git a/source/MaterialXRender/Image.h b/source/MaterialXRender/Image.h index b0ab820962..3bca364044 100644 --- a/source/MaterialXRender/Image.h +++ b/source/MaterialXRender/Image.h @@ -25,6 +25,9 @@ using ConstImagePtr = shared_ptr; /// A map from strings to images. using ImageMap = std::unordered_map; +/// A vetor of images. +using ImageVec = std::vector; + /// A pair of images. using ImagePair = std::pair; diff --git a/source/MaterialXRender/ShaderRenderer.h b/source/MaterialXRender/ShaderRenderer.h index ca9c1da072..c2d73b6563 100644 --- a/source/MaterialXRender/ShaderRenderer.h +++ b/source/MaterialXRender/ShaderRenderer.h @@ -118,7 +118,7 @@ class ShaderRenderer /// Save the current contents of the off-screen hardware buffer to disk. /// @param filePath Path to file to save rendered image to. - virtual void saveImage(const FilePath& filePath) = 0; + virtual void saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip) = 0; /// @} diff --git a/source/MaterialXRenderGlsl/GlslRenderer.cpp b/source/MaterialXRenderGlsl/GlslRenderer.cpp index 7c86059e84..5f0a6262a8 100644 --- a/source/MaterialXRenderGlsl/GlslRenderer.cpp +++ b/source/MaterialXRenderGlsl/GlslRenderer.cpp @@ -340,13 +340,12 @@ ImagePtr GlslRenderer::captureImage() return result; } -void GlslRenderer::saveImage(const FilePath& filePath) +void GlslRenderer::saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip) { StringVec errors; const string errorType("GLSL image save error."); - ImagePtr image = captureImage(); - if (!_imageHandler->saveImage(filePath, image, true)) + if (!_imageHandler->saveImage(filePath, image, verticalFlip)) { errors.push_back("Failed to save to file:" + filePath.asString()); throw ExceptionShaderRenderError(errorType, errors); diff --git a/source/MaterialXRenderGlsl/GlslRenderer.h b/source/MaterialXRenderGlsl/GlslRenderer.h index 7b17e15dbd..8bf7618f99 100644 --- a/source/MaterialXRenderGlsl/GlslRenderer.h +++ b/source/MaterialXRenderGlsl/GlslRenderer.h @@ -88,7 +88,7 @@ class GlslRenderer : public ShaderRenderer /// Save the current contents of the off-screen hardware buffer to disk. /// @param filePath Name of file to save rendered image to. - void saveImage(const FilePath& filePath) override; + void saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip) override; /// Return the GL frame buffer. GLFrameBufferPtr getFrameBuffer() const diff --git a/source/MaterialXRenderOsl/OslRenderer.cpp b/source/MaterialXRenderOsl/OslRenderer.cpp index f785ac6a04..8e46bfe385 100644 --- a/source/MaterialXRenderOsl/OslRenderer.cpp +++ b/source/MaterialXRenderOsl/OslRenderer.cpp @@ -96,6 +96,8 @@ void OslRenderer::renderOSL(const FilePath& dirPath, const string& shaderName, c // Set output image name. string outputFileName = shaderPath + "_osl.png"; + // Cache the output file name + _oslOutputFileName = outputFileName; // Use a known error file name to check string errorFile(shaderPath + "_render_errors.txt"); @@ -225,6 +227,8 @@ void OslRenderer::shadeOSL(const FilePath& dirPath, const string& shaderName, co // Set output image name. string outputFileName = shaderPath + ".testshade.png"; + // Cache the output file name + _oslOutputFileName = outputFileName; // Use a known error file name to check string errorFile(shaderPath + "_shade_errors.txt"); @@ -390,6 +394,8 @@ void OslRenderer::render() throw ExceptionShaderRenderError(errorType, errors); } + _oslOutputFileName.assign(EMPTY_STRING); + // Use testshade if (!_useTestRender) { @@ -410,13 +416,38 @@ void OslRenderer::render() ImagePtr OslRenderer::captureImage() { - // No-op: image capture is done as part of rendering. - return nullptr; + // As rendering goes to disk need to read the image back from disk + StringVec errors; + const string errorType("OSL image save error."); + + if (!_imageHandler || _oslOutputFileName.isEmpty()) + { + errors.push_back("Failed to read image: " + _oslOutputFileName.asString()); + throw ExceptionShaderRenderError(errorType, errors); + } + + string error; + ImagePtr returnImage = _imageHandler->acquireImage(_oslOutputFileName, false, nullptr, &error); + if (!returnImage) + { + errors.push_back("Failed to save to file: " + _oslOutputFileName.asString()); + errors.push_back(error); + throw ExceptionShaderRenderError(errorType, errors); + } + + return returnImage; } -void OslRenderer::saveImage(const FilePath& /*filePath*/) +void OslRenderer::saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip) { - // No-op: image save is done as part of rendering. + StringVec errors; + const string errorType("GLSL image save error."); + + if (!_imageHandler->saveImage(filePath, image, verticalFlip)) + { + errors.push_back("Failed to save to file: " + filePath.asString()); + throw ExceptionShaderRenderError(errorType, errors); + } } } // namespace MaterialX diff --git a/source/MaterialXRenderOsl/OslRenderer.h b/source/MaterialXRenderOsl/OslRenderer.h index bbe28de579..93f7516b19 100644 --- a/source/MaterialXRenderOsl/OslRenderer.h +++ b/source/MaterialXRenderOsl/OslRenderer.h @@ -98,7 +98,7 @@ class OslRenderer : public ShaderRenderer /// does not perform any action as render() produces images as part if it's /// execution. /// @param filePath Name of file to save rendered image to. - void saveImage(const FilePath& filePath) override; + void saveImage(const FilePath& filePath, ConstImagePtr image, bool verticalFlip) override; /// @} /// @name Compilation settings @@ -235,6 +235,8 @@ class OslRenderer : public ShaderRenderer FilePath _oslIncludePath; /// Output file path. File name does not include an extension FilePath _oslOutputFilePath; + /// Output image file name + FilePath _oslOutputFileName; /// Path to "testshade" executable FilePath _oslTestShadeExecutable; diff --git a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp index 895c913c4f..d8a02c29a2 100644 --- a/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp +++ b/source/MaterialXTest/MaterialXGenMdl/GenMdl.cpp @@ -170,13 +170,6 @@ void MdlShaderGeneratorTester::compileSource(const std::vector& so } else { - // Make this a build option - //std::string renderExec("D:/Work/materialx/df_cuda_rel_325000.1814/df_cuda.exe"); - //if (renderExec.empty()) - //{ - // return; - //} - std::string renderCommand = renderExec; for (const std::string& extraPath : extraModulePaths) { diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp index 23b467e847..9132d7953b 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.cpp @@ -977,6 +977,11 @@ bool TestSuiteOptions::readOptions(const std::string& optionFile) const std::string EXTERNAL_LIBRARY_PATHS("externalLibraryPaths"); const std::string EXTERNAL_TEST_PATHS("externalTestPaths"); const std::string APPLY_LATEST_UPDATES("applyFutureUpdates"); + const std::string WEDGE_FILES("wedgeFiles"); + const std::string WEDGE_PARAMETERS("wedgeParameters"); + const std::string WEDGE_RANGE_MIN("wedgeRangeMin"); + const std::string WEDGE_RANGE_MAX("wedgeRangeMax"); + const std::string WEDGE_STEPS("wedgeSteps"); overrideFiles.clear(); dumpGeneratedCode = false; @@ -1106,6 +1111,27 @@ bool TestSuiteOptions::readOptions(const std::string& optionFile) externalTestPaths.append(mx::FilePath(l)); } } + + else if (name == WEDGE_FILES) + { + wedgeFiles = mx::splitString(p->getValueString(), ","); + } + else if (name == WEDGE_PARAMETERS) + { + wedgeParameters = mx::splitString(p->getValueString(), ","); + } + else if (name == WEDGE_STEPS) + { + wedgeSteps = val->asA(); + } + else if (name == WEDGE_RANGE_MIN) + { + wedgeRangeMin = val->asA(); + } + else if (name == WEDGE_RANGE_MAX) + { + wedgeRangeMax = val->asA(); + } else if (name == APPLY_LATEST_UPDATES) { applyFutureUpdates = p->getValue()->asA(); diff --git a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h index a99333de9a..b57453df72 100644 --- a/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h +++ b/source/MaterialXTest/MaterialXGenShader/GenShaderUtil.h @@ -141,6 +141,13 @@ class TestSuiteOptions // Additional testPaths paths mx::FileSearchPath externalTestPaths; + // Wedge parameters + mx::StringVec wedgeFiles; + mx::StringVec wedgeParameters; + mx::FloatVec wedgeRangeMin; + mx::FloatVec wedgeRangeMax; + mx::IntVec wedgeSteps; + // Apply updates for future versions bool applyFutureUpdates; }; diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp index 0693a48216..eb94ea9a64 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.cpp +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.cpp @@ -362,7 +362,119 @@ bool ShaderRenderTester::validate(const mx::FilePathVec& testRootPaths, const mx mx::InterfaceElementPtr nodeGraphImpl = nodeGraph ? nodeGraph->getImplementation() : nullptr; usedImpls.insert(nodeGraphImpl ? nodeGraphImpl->getName() : impl->getName()); } - runRenderer(elementName, targetElement, context, doc, log, options, profileTimes, imageSearchPath, outputPath); + + const mx::StringVec& wedgeFiles = options.wedgeFiles; + const mx::StringVec& wedgeParameters = options.wedgeParameters; + const mx::FloatVec& wedgeRangeMin = options.wedgeRangeMin; + const mx::FloatVec& wedgeRangeMax = options.wedgeRangeMax; + const mx::IntVec& wedgeSteps = options.wedgeSteps; + bool performWedge = (!wedgeFiles.empty()) && + wedgeFiles.size() == wedgeParameters.size() && + wedgeFiles.size() == wedgeRangeMin.size() && + wedgeFiles.size() == wedgeRangeMax.size() && + wedgeFiles.size() == wedgeSteps.size(); + + if (!performWedge) + { + runRenderer(elementName, targetElement, context, doc, log, options, profileTimes, imageSearchPath, outputPath, nullptr); + } + else + { + mx::ImageVec imageVec; + for (size_t f = 0; f < wedgeFiles.size(); f++) + { + const std::string& wedgeFile = wedgeFiles[f]; + if (wedgeFile != file) + { + continue; + } + + // Make this a utility + std::string parameterPath = wedgeParameters[f]; + mx::ElementPtr uniformElement = doc->getDescendant(parameterPath); + if (!uniformElement) + { + std::string nodePath = mx::parentNamePath(parameterPath); + mx::ElementPtr uniformParent = doc->getDescendant(nodePath); + if (uniformParent) + { + mx::NodePtr uniformNode = uniformParent->asA(); + if (uniformNode) + { + mx::StringVec pathVec = mx::splitNamePath(parameterPath); + uniformNode->addInputFromNodeDef(pathVec[pathVec.size() - 1]); + } + } + } + uniformElement = doc->getDescendant(parameterPath); + mx::ValueElementPtr valueElement = uniformElement ? uniformElement->asA() : nullptr; + if (!valueElement) + { + continue; + } + + mx::ValuePtr origPropertyValue(valueElement ? valueElement->getValue() : nullptr); + mx::ValuePtr newValue = valueElement->getValue(); + + float wedgePropertyMin = wedgeRangeMin[f]; + float wedgePropertyMax = wedgeRangeMax[f]; + int wedgeImageCount = std::max(wedgeSteps[f], 2); + + float wedgePropertyStep = (wedgePropertyMax - wedgePropertyMin) / (wedgeImageCount - 1); + for (int w = 0; w < wedgeImageCount; w++) + { + bool setValue = false; + float propertyValue = (w == wedgeImageCount - 1) ? wedgePropertyMax : wedgePropertyMin + wedgePropertyStep * w; + if (origPropertyValue->isA()) + { + valueElement->setValue(static_cast(propertyValue)); + setValue = true; + } + else if (origPropertyValue->isA()) + { + valueElement->setValue(propertyValue); + setValue = true; + } + else if (origPropertyValue->isA()) + { + mx::Vector2 val(propertyValue, propertyValue); + valueElement->setValue(val); + setValue = true; + } + else if (origPropertyValue->isA() || + origPropertyValue->isA()) + { + mx::Vector3 val(propertyValue, propertyValue, propertyValue); + valueElement->setValue(val); + setValue = true; + } + else if (origPropertyValue->isA() || + origPropertyValue->isA()) + { + mx::Vector4 val(propertyValue, propertyValue, propertyValue, origPropertyValue->isA() ? 1.0f : propertyValue); + valueElement->setValue(val); + setValue = true; + } + + if (setValue) + { + runRenderer(elementName, targetElement, context, doc, log, options, profileTimes, imageSearchPath, outputPath, &imageVec); + } + } + + if (!imageVec.empty()) + { + mx::ImagePtr wedgeImage = mx::createImageStrip(imageVec); + if (wedgeImage) + { + std::string wedgeFileName = mx::createValidName(mx::replaceSubstrings(parameterPath, pathMap)); + wedgeFileName += "_" + _languageTargetString + ".bmp"; + mx::FilePath wedgePath = outputPath / wedgeFileName; + saveImage(wedgePath, wedgeImage, true); + } + } + } + } } } } diff --git a/source/MaterialXTest/MaterialXRender/RenderUtil.h b/source/MaterialXTest/MaterialXRender/RenderUtil.h index 2b2076bfa4..842783fb14 100644 --- a/source/MaterialXTest/MaterialXRender/RenderUtil.h +++ b/source/MaterialXTest/MaterialXRender/RenderUtil.h @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -214,7 +215,11 @@ class ShaderRenderTester const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath = ".") = 0; + const std::string& outputPath = ".", + mx::ImageVec* imageVec = nullptr) = 0; + + // Save an image + virtual bool saveImage(const mx::FilePath&, mx::ConstImagePtr, bool) const { return false; }; // Create a list of generation options based on unit test options // These options will override the original generation context options. diff --git a/source/MaterialXTest/MaterialXRenderArnold/RenderArnold.cpp b/source/MaterialXTest/MaterialXRenderArnold/RenderArnold.cpp index da253c9eba..79e3098d25 100644 --- a/source/MaterialXTest/MaterialXRenderArnold/RenderArnold.cpp +++ b/source/MaterialXTest/MaterialXRenderArnold/RenderArnold.cpp @@ -42,7 +42,8 @@ class ArnoldShaderRenderTester : public RenderUtil::ShaderRenderTester const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath = ".") override; + const std::string& outputPath = ".", + mx::ImageVec* imageVec = nullptr) override; }; void ArnoldShaderRenderTester::createRenderer(std::ostream& /*log*/) @@ -57,7 +58,8 @@ bool ArnoldShaderRenderTester::runRenderer(const std::string& shaderName, const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& /*imageSearchPath*/, - const std::string& outputPath) + const std::string& outputPath, + mx::ImageVec* /*returnImage*/) { RenderUtil::AdditiveScopedTimer totalArnoldTime(profileTimes.languageTimes.totalTime, "Arnold total time"); diff --git a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp index 1adafe68c6..28f1b0385d 100644 --- a/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp +++ b/source/MaterialXTest/MaterialXRenderGlsl/RenderGlsl.cpp @@ -19,8 +19,8 @@ #include -#include #include +#include #if defined(MATERIALX_BUILD_OIIO) #include #endif @@ -60,7 +60,10 @@ class GlslShaderRenderTester : public RenderUtil::ShaderRenderTester const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath = ".") override; + const std::string& outputPath = ".", + mx::ImageVec* imageVec = nullptr) override; + + bool saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool verticalFlip) const override; mx::GlslRendererPtr _renderer; mx::LightHandlerPtr _lightHandler; @@ -119,12 +122,12 @@ void GlslShaderRenderTester::createRenderer(std::ostream& log) _renderer->initialize(); // Set image handler on renderer -#if defined(MATERIALX_BUILD_OIIO) - mx::OiioImageLoaderPtr stbLoader = mx::OiioImageLoader::create(); -#else mx::StbImageLoaderPtr stbLoader = mx::StbImageLoader::create(); -#endif mx::ImageHandlerPtr imageHandler = mx::GLTextureHandler::create(stbLoader); +#if defined(MATERIALX_BUILD_OIIO) + mx::OiioImageLoaderPtr oiioLoader = mx::OiioImageLoader::create(); + imageHandler->addLoader(oiioLoader); +#endif _renderer->setImageHandler(imageHandler); // Set light handler. @@ -146,6 +149,11 @@ void GlslShaderRenderTester::createRenderer(std::ostream& log) REQUIRE(initialized); } +bool GlslShaderRenderTester::saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool verticalFlip) const +{ + return _renderer->getImageHandler()->saveImage(filePath, image, verticalFlip); +} + // If these streams don't exist add them for testing purposes // void addAdditionalTestStreams(mx::MeshPtr mesh) @@ -258,7 +266,8 @@ bool GlslShaderRenderTester::runRenderer(const std::string& shaderName, const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath) + const std::string& outputPath, + mx::ImageVec* imageVec) { RenderUtil::AdditiveScopedTimer totalGLSLTime(profileTimes.languageTimes.totalTime, "GLSL total time"); @@ -501,7 +510,15 @@ bool GlslShaderRenderTester::runRenderer(const std::string& shaderName, { RenderUtil::AdditiveScopedTimer ioTimer(profileTimes.languageTimes.imageSaveTime, "GLSL image save time"); std::string fileName = shaderPath + "_glsl.png"; - _renderer->saveImage(fileName); + mx::ImagePtr image = _renderer->captureImage(); + if (image) + { + _renderer->saveImage(fileName, image, true); + if (imageVec) + { + imageVec->push_back(image); + } + } } } diff --git a/source/MaterialXTest/MaterialXRenderOgsFx/RenderOgsFx.cpp b/source/MaterialXTest/MaterialXRenderOgsFx/RenderOgsFx.cpp index d25184c6bb..539d55c254 100644 --- a/source/MaterialXTest/MaterialXRenderOgsFx/RenderOgsFx.cpp +++ b/source/MaterialXTest/MaterialXRenderOgsFx/RenderOgsFx.cpp @@ -42,7 +42,8 @@ class OgsFxShaderRenderTester : public RenderUtil::ShaderRenderTester const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath = ".") override; + const std::string& outputPath = ".", + mx::ImageVec* imageVec = nullptr) override; mx::LightHandlerPtr _lightHandler; }; @@ -89,7 +90,8 @@ bool OgsFxShaderRenderTester::runRenderer(const std::string& shaderName, const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& /*imageSearchPath*/, - const std::string& outputPath) + const std::string& outputPath, + mx::ImageVec* /*imageVec*/) { RenderUtil::AdditiveScopedTimer totalTime(profileTimes.languageTimes.totalTime, "OgsFx total time"); diff --git a/source/MaterialXTest/MaterialXRenderOsl/RenderOsl.cpp b/source/MaterialXTest/MaterialXRenderOsl/RenderOsl.cpp index 081f839b67..c1cfbfef86 100644 --- a/source/MaterialXTest/MaterialXRenderOsl/RenderOsl.cpp +++ b/source/MaterialXTest/MaterialXRenderOsl/RenderOsl.cpp @@ -13,6 +13,11 @@ #include +#include +#if defined(MATERIALX_BUILD_OIIO) +#include +#endif + namespace mx = MaterialX; class OslShaderRenderTester : public RenderUtil::ShaderRenderTester @@ -44,8 +49,15 @@ class OslShaderRenderTester : public RenderUtil::ShaderRenderTester const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath = ".") override; + const std::string& outputPath = ".", + mx::ImageVec* imageVec = nullptr) override; + + bool saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool /*verticalFlip*/) const override + { + return _renderer->getImageHandler()->saveImage(filePath, image, false); + } + mx::ImageLoaderPtr _imageLoader; mx::OslRendererPtr _renderer; }; @@ -55,6 +67,7 @@ void OslShaderRenderTester::createRenderer(std::ostream& log) bool initialized = false; _renderer = mx::OslRenderer::create(); + _imageLoader = mx::StbImageLoader::create(); // Set up additional utilities required to run OSL testing including // oslc and testrender paths and OSL include path @@ -68,7 +81,14 @@ void OslShaderRenderTester::createRenderer(std::ostream& log) try { _renderer->initialize(); - _renderer->setImageHandler(nullptr); + + mx::StbImageLoaderPtr stbLoader = mx::StbImageLoader::create(); + mx::ImageHandlerPtr imageHandler = mx::ImageHandler::create(stbLoader); +#if defined(MATERIALX_BUILD_OIIO) + mx::OiioImageLoaderPtr oiioLoader = mx::OiioImageLoader::create(); + imageHandler->addLoader(oiioLoader); +#endif + _renderer->setImageHandler(imageHandler); _renderer->setLightHandler(nullptr); initialized = true; @@ -107,7 +127,8 @@ bool OslShaderRenderTester::runRenderer(const std::string& shaderName, const GenShaderUtil::TestSuiteOptions& testOptions, RenderUtil::RenderProfileTimes& profileTimes, const mx::FileSearchPath& imageSearchPath, - const std::string& outputPath) + const std::string& outputPath, + mx::ImageVec* imageVec) { RenderUtil::AdditiveScopedTimer totalOSLTime(profileTimes.languageTimes.totalTime, "OSL total time"); @@ -244,7 +265,9 @@ bool OslShaderRenderTester::runRenderer(const std::string& shaderName, } } // Bind IBL image name overrides. - std::string envmap_filename("string envmap_filename \"resources/Lights/san_giuseppe_bridge.hdr\";\n"); + std::string envmap_filename("string envmap_filename \""); + envmap_filename += testOptions.radianceIBLPath; + envmap_filename += "\";\n"; envOverrides.push_back(envmap_filename); _renderer->setShaderParameterOverrides(overrides); @@ -275,6 +298,10 @@ bool OslShaderRenderTester::runRenderer(const std::string& shaderName, { RenderUtil::AdditiveScopedTimer renderTimer(profileTimes.languageTimes.renderTime, "OSL render time"); _renderer->render(); + if (imageVec) + { + imageVec->push_back(_renderer->captureImage()); + } } } else diff --git a/source/MaterialXView/Material.h b/source/MaterialXView/Material.h index 507a4cf74f..fdd1e6b435 100644 --- a/source/MaterialXView/Material.h +++ b/source/MaterialXView/Material.h @@ -227,7 +227,7 @@ class Material bool _hasTransparency; mx::StringSet _uniformVariable; - std::vector _boundImages; + mx::ImageVec _boundImages; }; #endif // MATERIALXVIEW_MATERIAL_H diff --git a/source/MaterialXView/Viewer.cpp b/source/MaterialXView/Viewer.cpp index d7801ebb7c..9feb2cd5a4 100644 --- a/source/MaterialXView/Viewer.cpp +++ b/source/MaterialXView/Viewer.cpp @@ -1041,6 +1041,7 @@ void Viewer::loadDocument(const mx::FilePath& filename, mx::DocumentPtr librarie { // Set up read options. mx::XmlReadOptions readOptions; + readOptions.applyFutureUpdates = true; readOptions.readXIncludeFunction = [](mx::DocumentPtr doc, const mx::FilePath& filename, const mx::FileSearchPath& searchPath, const mx::XmlReadOptions* options) { @@ -1477,8 +1478,9 @@ void Viewer::loadStandardLibraries() try { mx::XmlReadOptions readOptions; + readOptions.applyFutureUpdates = true; _stdLib = mx::createDocument(); - _xincludeFiles = mx::loadLibraries(_libraryFolders, _searchPath, _stdLib); + _xincludeFiles = mx::loadLibraries(_libraryFolders, _searchPath, _stdLib, mx::StringSet(), &readOptions); if (_xincludeFiles.empty()) { std::cerr << "Could not find standard data libraries on the given search path: " << _searchPath.asString() << std::endl; diff --git a/source/PyMaterialX/PyMaterialXRender/PyShaderRenderer.cpp b/source/PyMaterialX/PyMaterialXRender/PyShaderRenderer.cpp index 4d7cea7096..1f53588c26 100644 --- a/source/PyMaterialX/PyMaterialXRender/PyShaderRenderer.cpp +++ b/source/PyMaterialX/PyMaterialXRender/PyShaderRenderer.cpp @@ -65,13 +65,15 @@ class PyShaderRenderer : public mx::ShaderRenderer ); } - void saveImage(const mx::FilePath& filePath) override + void saveImage(const mx::FilePath& filePath, mx::ConstImagePtr image, bool verticalFlip) override { PYBIND11_OVERLOAD_PURE( void, mx::ShaderRenderer, saveImage, - filePath + filePath, + image, + verticalFlip ); } };