From 0d19d5440ef0223f84d521dd5baf7acf35a116ac Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Tue, 12 Jun 2018 12:07:40 -0700 Subject: [PATCH 01/36] Version 3.1 --- Framework/Source/Falcor.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/Source/Falcor.h b/Framework/Source/Falcor.h index 1f475b14d..6da21594f 100644 --- a/Framework/Source/Falcor.h +++ b/Framework/Source/Falcor.h @@ -158,7 +158,7 @@ #endif #define FALCOR_MAJOR_VERSION 3 -#define FALCOR_MINOR_VERSION 0 +#define FALCOR_MINOR_VERSION 1 #define FALCOR_DEV_STAGE "" -#define FALCOR_DEV_REVISION 4 -#define FALCOR_VERSION_STRING "3.0.4" \ No newline at end of file +#define FALCOR_DEV_REVISION 0 +#define FALCOR_VERSION_STRING "3.1" \ No newline at end of file From a43fa6465100d82f363afb378b44a6847cde177a Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Tue, 12 Jun 2018 12:08:39 -0700 Subject: [PATCH 02/36] Fixed invalid texture resolve in ForwardRenderer sample when MSAA sample count was set to 1 --- Samples/ForwardRenderer/ForwardRenderer.h | 1 + .../ForwardRendererControls.cpp | 35 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/Samples/ForwardRenderer/ForwardRenderer.h b/Samples/ForwardRenderer/ForwardRenderer.h index ca17883f6..f61e6d173 100644 --- a/Samples/ForwardRenderer/ForwardRenderer.h +++ b/Samples/ForwardRenderer/ForwardRenderer.h @@ -197,6 +197,7 @@ class ForwardRenderer : public Renderer enum class AAMode { + None, MSAA, TAA, FXAA diff --git a/Samples/ForwardRenderer/ForwardRendererControls.cpp b/Samples/ForwardRenderer/ForwardRendererControls.cpp index 2ad4e3785..392be2f99 100644 --- a/Samples/ForwardRenderer/ForwardRendererControls.cpp +++ b/Samples/ForwardRenderer/ForwardRendererControls.cpp @@ -29,7 +29,6 @@ Gui::DropdownList kSampleCountList = { - { 1, "1" }, { 2, "2" }, { 4, "4" }, { 8, "8" }, @@ -37,9 +36,10 @@ Gui::DropdownList kSampleCountList = const Gui::DropdownList aaModeList = { - { 0, "MSAA" }, - { 1, "TAA" }, - { 2, "FXAA" } + { 0, "None"}, + { 1, "MSAA" }, + { 2, "TAA" }, + { 3, "FXAA" } }; @@ -83,6 +83,8 @@ void ForwardRenderer::applyAaMode(SampleCallbacks* pSample) { if (mLightingPass.pProgram == nullptr) return; + assert(mAAMode == AAMode::MSAA ? mMSAASampleCount > 1 : true); + uint32_t w = pSample->getCurrentFbo()->getWidth(); uint32_t h = pSample->getCurrentFbo()->getHeight(); @@ -93,7 +95,17 @@ void ForwardRenderer::applyAaMode(SampleCallbacks* pSample) // Release the TAA FBOs mTAA.resetFbos(); - if (mAAMode == AAMode::MSAA || mAAMode == AAMode::FXAA) + if (mAAMode == AAMode::TAA) + { + mLightingPass.pProgram->removeDefine("INTERPOLATION_MODE"); + mLightingPass.pProgram->addDefine("_OUTPUT_MOTION_VECTORS"); + fboDesc.setColorTarget(2, ResourceFormat::RG16Float); + + Fbo::Desc taaFboDesc; + taaFboDesc.setColorTarget(0, ResourceFormat::RGBA8UnormSrgb); + mTAA.createFbos(w, h, taaFboDesc); + } + else { mLightingPass.pProgram->removeDefine("_OUTPUT_MOTION_VECTORS"); applyLightingProgramControl(SuperSampling); @@ -106,24 +118,13 @@ void ForwardRenderer::applyAaMode(SampleCallbacks* pSample) resolveDesc.setColorTarget(1, ResourceFormat::RGBA8Unorm).setColorTarget(2, ResourceFormat::R32Float); mpResolveFbo = FboHelper::create2D(w, h, resolveDesc); } - - if (mAAMode == AAMode::FXAA) + else if (mAAMode == AAMode::FXAA) { Fbo::Desc resolveDesc; resolveDesc.setColorTarget(0, pSample->getCurrentFbo()->getColorTexture(0)->getFormat()); mpResolveFbo = FboHelper::create2D(w, h, resolveDesc); } } - else if (mAAMode == AAMode::TAA) - { - mLightingPass.pProgram->removeDefine("INTERPOLATION_MODE"); - mLightingPass.pProgram->addDefine("_OUTPUT_MOTION_VECTORS"); - fboDesc.setColorTarget(2, ResourceFormat::RG16Float); - - Fbo::Desc taaFboDesc; - taaFboDesc.setColorTarget(0, ResourceFormat::RGBA8UnormSrgb); - mTAA.createFbos(w, h, taaFboDesc); - } mpMainFbo = FboHelper::create2D(w, h, fboDesc); mpDepthPassFbo = Fbo::create(); From 7b4dfe22e40fd3b01b9259fe2d3906dd17957f7b Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Tue, 12 Jun 2018 19:27:55 -0700 Subject: [PATCH 03/36] Adds simple function to display reflection for buffer in imgui --- Framework/Source/API/ConstantBuffer.cpp | 43 +++++++++++++++++++ Framework/Source/API/ConstantBuffer.h | 5 +++ .../Graphics/Program/ProgramReflection.h | 2 + .../ForwardRendererControls.cpp | 3 ++ 4 files changed, 53 insertions(+) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 6f89a6ecb..a91b79f93 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -34,6 +34,11 @@ #include "Graphics/Program/ProgramReflection.h" #include "API/Device.h" +#include "Renderer.h" +#include "utils/Gui.h" + + + namespace Falcor { ConstantBuffer::~ConstantBuffer() = default; @@ -82,4 +87,42 @@ namespace Falcor } return mpCbv; } + + void ConstantBuffer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) + { + const auto& reflectionDescMap = getBufferReflector()->asResourceType()->getOffsetDescMap(); + + + if (reflectionDescMap.size()) + { + size_t offset = 0; + + if (pGui->beginGroup("Constant Buffer")) + { + std::string displayString; + for (const auto& reflectionDesc : reflectionDescMap) + { + displayString = "Offset: "; + + displayString.append(std::to_string(offset)); + + displayString.append(" Size: "); + displayString.append(std::to_string(reflectionDesc.first)); + + offset += reflectionDesc.first; + + displayString.append(" Type: "); + displayString.append(to_string(reflectionDesc.second.type)); + + displayString.append(" Count: "); + displayString.append(std::to_string(reflectionDesc.second.count)); + + pGui->addText(displayString.c_str()); + pGui->addSeparator(); + } + + pGui->endGroup(); + } + } + } } \ No newline at end of file diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index 698ce066d..f5aec75a0 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -35,6 +35,9 @@ namespace Falcor { class Sampler; + // Forward declares for gui draw func + class SampleCallbacks; + class Gui; /** Abstracts a Constant/Uniform buffer. When accessing a variable by name, you can only use a name which points to a basic Type, or an array of basic Type (so if you want the start of a structure, ask for the first field in the struct). @@ -133,6 +136,8 @@ namespace Falcor return VariablesBuffer::setVariableArray(name, 0, pValue, count); } + void onGuiRender(SampleCallbacks* pSample, Gui* pGui); + virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; ConstantBufferView::SharedPtr getCbv() const; diff --git a/Framework/Source/Graphics/Program/ProgramReflection.h b/Framework/Source/Graphics/Program/ProgramReflection.h index 986aae995..c8937ac83 100644 --- a/Framework/Source/Graphics/Program/ProgramReflection.h +++ b/Framework/Source/Graphics/Program/ProgramReflection.h @@ -392,6 +392,8 @@ namespace Falcor */ const OffsetDesc& getOffsetDesc(size_t offset) const; + const OffsetDescMap& getOffsetDescMap() const { return mOffsetDescMap; } + bool operator==(const ReflectionResourceType& other) const; bool operator==(const ReflectionType& other) const override; private: diff --git a/Samples/ForwardRenderer/ForwardRendererControls.cpp b/Samples/ForwardRenderer/ForwardRendererControls.cpp index 392be2f99..c63d3dfc8 100644 --- a/Samples/ForwardRenderer/ForwardRendererControls.cpp +++ b/Samples/ForwardRenderer/ForwardRendererControls.cpp @@ -350,5 +350,8 @@ void ForwardRenderer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) { applyLightingProgramControl(ControlID::EnableHashedAlpha); } + + ConstantBuffer::SharedPtr pCB = mLightingPass.pVars->getConstantBuffer("PerFrameCB"); + pCB->onGuiRender(pSample, pGui); } } From 2f28969c603e641d2e2adcb6928859bedf071b94 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Wed, 13 Jun 2018 16:20:43 -0700 Subject: [PATCH 04/36] Added TGA and BMP export support. Also added a util for joining strings --- Framework/Source/Utils/Bitmap.cpp | 111 +++++++++++++++++---------- Framework/Source/Utils/Bitmap.h | 2 + Framework/Source/Utils/StringUtils.h | 20 +++++ 3 files changed, 93 insertions(+), 40 deletions(-) diff --git a/Framework/Source/Utils/Bitmap.cpp b/Framework/Source/Utils/Bitmap.cpp index 7a92188ad..57b2132c6 100644 --- a/Framework/Source/Utils/Bitmap.cpp +++ b/Framework/Source/Utils/Bitmap.cpp @@ -31,6 +31,7 @@ #include "Utils/Platform/OS.h" #include "API/Device.h" #include +#include "StringUtils.h" namespace Falcor { @@ -163,6 +164,10 @@ namespace Falcor return FIF_PNG; case Bitmap::FileFormat::JpegFile: return FIF_JPEG; + case Bitmap::FileFormat::TgaFile: + return FIF_TARGA; + case Bitmap::FileFormat::BmpFile: + return FIF_BMP; case Bitmap::FileFormat::PfmFile: return FIF_PFM; case Bitmap::FileFormat::ExrFile: @@ -170,7 +175,7 @@ namespace Falcor default: should_not_get_here(); } - return FIF_PNG; + return FIF_PNG; } static FREE_IMAGE_TYPE getImageType(uint32_t bytesPerPixel) @@ -224,45 +229,7 @@ namespace Falcor } } - if (fileFormat == Bitmap::FileFormat::PngFile) - { - pImage = FreeImage_ConvertFromRawBits((BYTE*)pData, width, height, bytesPerPixel * width, bytesPerPixel * 8, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, isTopDown); - if(is_set(exportFlags, ExportFlags::ExportAlpha) == false) - { - auto pTemp = pImage; - pImage = FreeImage_ConvertTo24Bits(pImage); - FreeImage_Unload(pTemp); - } - flags = PNG_Z_BEST_COMPRESSION; - - if(is_set(exportFlags, ExportFlags::Uncompressed)) - { - flags = PNG_Z_NO_COMPRESSION; - } - - if(is_set(exportFlags, ExportFlags::Lossy)) - { - logError("Bitmap::saveImage: PNG does not support lossy compression mode."); - return; - } - } - else if (fileFormat == Bitmap::FileFormat::JpegFile) - { - FIBITMAP* pTemp = FreeImage_ConvertFromRawBits((BYTE*)pData, width, height, bytesPerPixel * width, bytesPerPixel * 8, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, isTopDown); - pImage = FreeImage_ConvertTo24Bits(pTemp); - FreeImage_Unload(pTemp); - if(is_set(exportFlags, ExportFlags::Lossy) == false || is_set(exportFlags, ExportFlags::Uncompressed)) - { - flags = JPEG_QUALITYSUPERB | JPEG_SUBSAMPLING_444; - } - - if(is_set(exportFlags, ExportFlags::ExportAlpha)) - { - logError("Bitmap::saveImage: JPEG does not support alpha channel."); - return; - } - } - else if (fileFormat == Bitmap::FileFormat::PfmFile || fileFormat == Bitmap::FileFormat::ExrFile) + if (fileFormat == Bitmap::FileFormat::PfmFile || fileFormat == Bitmap::FileFormat::ExrFile) { if(bytesPerPixel != 16 && bytesPerPixel != 12) { @@ -330,6 +297,70 @@ namespace Falcor } } } + else + { + FIBITMAP* pTemp = FreeImage_ConvertFromRawBits((BYTE*)pData, width, height, bytesPerPixel * width, bytesPerPixel * 8, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, isTopDown); + if(is_set(exportFlags, ExportFlags::ExportAlpha) || fileFormat == Bitmap::FileFormat::JpegFile) + { + pImage = FreeImage_ConvertTo24Bits(pTemp); + FreeImage_Unload(pTemp); + } + else + { + pImage = pTemp; + } + + std::vector warnings; + switch(fileFormat) + { + case FileFormat::JpegFile: + if (is_set(exportFlags, ExportFlags::Lossy) == false || is_set(exportFlags, ExportFlags::Uncompressed)) + { + flags = JPEG_QUALITYSUPERB | JPEG_SUBSAMPLING_444; + } + if (is_set(exportFlags, ExportFlags::ExportAlpha)) + { + warnings.push_back("JPEG format does not support alpha channel."); + } + break; + + // Lossless formats + case FileFormat::PngFile: + flags = is_set(exportFlags, ExportFlags::Uncompressed) ? flags = PNG_Z_NO_COMPRESSION : PNG_Z_BEST_COMPRESSION; + + if (is_set(exportFlags, ExportFlags::Lossy)) + { + warnings.push_back("PNG format does not support lossy compression mode."); + } + break; + + case FileFormat::TgaFile: + if (is_set(exportFlags, ExportFlags::Lossy)) + { + warnings.push_back("TGA format does not support lossy compression mode."); + } + break; + + case FileFormat::BmpFile: + if (is_set(exportFlags, ExportFlags::Lossy)) + { + warnings.push_back("BMP format does not support lossy compression mode."); + } + if (is_set(exportFlags, ExportFlags::ExportAlpha)) + { + warnings.push_back("BMP format does not support alpha channel."); + } + break; + + default: + should_not_get_here(); + } + + if(warnings.empty() == false) + { + logWarning("Bitmap::saveImage: " + joinStrings(warnings, " ")); + } + } FreeImage_Save(toFreeImageFormat(fileFormat), pImage, filename.c_str(), flags); FreeImage_Unload(pImage); diff --git a/Framework/Source/Utils/Bitmap.h b/Framework/Source/Utils/Bitmap.h index 2d8ec7504..4c3aa6dca 100644 --- a/Framework/Source/Utils/Bitmap.h +++ b/Framework/Source/Utils/Bitmap.h @@ -47,6 +47,8 @@ namespace Falcor { PngFile, //< PNG file for lossless compressed 8-bits images with optional alpha JpegFile, //< JPEG file for lossy compressed 8-bits images without alpha + TgaFile, //< TGA file for lossless uncompressed 8-bits images with optional alpha + BmpFile, //< BMP file for lossless uncompressed 8-bits images with optional alpha PfmFile, //< PFM file for floating point HDR images with 32-bit float per channel ExrFile, //< EXR file for floating point HDR images with 16-bit float per channel }; diff --git a/Framework/Source/Utils/StringUtils.h b/Framework/Source/Utils/StringUtils.h index 7401bbc8a..567408371 100644 --- a/Framework/Source/Utils/StringUtils.h +++ b/Framework/Source/Utils/StringUtils.h @@ -121,6 +121,26 @@ namespace Falcor return vec; } + /** Join an array of strings separated by another set string + \param[in] strings Array of strings to join. + \param[in] separator String placed between each string to be joined. + \return Joined string. + */ + inline std::string joinStrings(const std::vector& strings, const std::string& separator) + { + std::string result; + for(auto it = strings.begin(); it != strings.end(); it++) + { + result += *it; + + if(it != strings.end() - 1) + { + result += separator; + } + } + return result; + } + /** Remove leading whitespaces (space, tab, newline, carriage-return) \param[in] str String to operate on \return String with leading whitespaces removed. From 5767d95fd7cdb147beadebc7eaccdc5e9d637f7d Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Thu, 14 Jun 2018 12:44:10 -0700 Subject: [PATCH 05/36] String version of Gui::addTextBox now actually updates the string parameter --- Framework/Source/Utils/Gui.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 7b30bf13b..62c96d346 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -540,14 +540,18 @@ namespace Falcor char buf[maxSize]; copyStringToBuffer(buf, maxSize, text); + bool result = false; if (lineCount > 1) { - return ImGui::InputTextMultiline(label, buf, maxSize, ImVec2(-1.0f, ImGui::GetTextLineHeight() * lineCount), flags); + result = ImGui::InputTextMultiline(label, buf, maxSize, ImVec2(-1.0f, ImGui::GetTextLineHeight() * lineCount), flags); } else { - return ImGui::InputText(label, buf, maxSize, flags); + result = ImGui::InputText(label, buf, maxSize, flags); } + + text = std::string(buf); + return result; } void Gui::addTooltip(const char tip[], bool sameLine) From bc6efde8d9388c87929baa5c5a96448733b0349d Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Fri, 15 Jun 2018 14:45:19 -0700 Subject: [PATCH 06/36] Updated changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5b00179a..9c71021b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,11 @@ +v3.1 +------ +- Added support for exporting BMP and TGA images. + +Bug Fixes: +- Fixed crash when setting ForwardRenderer sample to MSAA with sample count 1 +- std::string version of Gui::addTextBox() now correctly updates the user's string + v3.0.4 ------ - Updated Slang to 0.10.24 From d9fef8391a387d6426b13bfac51181062e2d271f Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 15 Jun 2018 14:49:13 -0700 Subject: [PATCH 07/36] Adds gui display for constant buffers using the program reflection. --- Framework/Source/API/ConstantBuffer.cpp | 427 ++++++++++++++++++++++-- Framework/Source/API/ConstantBuffer.h | 9 +- Framework/Source/Utils/Gui.cpp | 10 +- Framework/Source/Utils/Gui.h | 11 +- 4 files changed, 426 insertions(+), 31 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index a91b79f93..86219b8b7 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -88,41 +88,428 @@ namespace Falcor return mpCbv; } - void ConstantBuffer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) + const std::string val_to_string(ReflectionBasicType::Type type, const uint8_t* data) { - const auto& reflectionDescMap = getBufferReflector()->asResourceType()->getOffsetDescMap(); + std::string asString("{ "); + size_t offset = 0; + +#define val_2_string_from_type_(typeName, baseType) \ + case typeName: \ + asString.append(std::to_string( *reinterpret_cast(data + offset) )); \ + offset += sizeof(baseType) +#define val_2_string_from_type(typeName, baseType, endString) \ + val_2_string_from_type_(typeName, baseType); \ + asString.append(endString) - if (reflectionDescMap.size()) + switch (type) { - size_t offset = 0; + val_2_string_from_type(ReflectionBasicType::Type::Bool4, bool, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Bool3, bool, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Bool2, bool, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Bool, bool); + break; + val_2_string_from_type(ReflectionBasicType::Type::Uint4, uint32_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Uint3, uint32_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Uint2, uint32_t, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Uint, uint32_t); + break; + val_2_string_from_type(ReflectionBasicType::Type::Uint64_4, uint64_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Uint64_3, uint64_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Uint64_2, uint64_t, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Uint64, uint64_t); + break; + val_2_string_from_type(ReflectionBasicType::Type::Int4, int32_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Int3, int32_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Int2, int32_t, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Int, int32_t); + break; + val_2_string_from_type(ReflectionBasicType::Type::Int64_4, int64_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Int64_3, int64_t, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Int64_2, int64_t, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Int64, int64_t); + break; + val_2_string_from_type(ReflectionBasicType::Type::Float4, float, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Float3, float, " , "); + val_2_string_from_type(ReflectionBasicType::Type::Float2, float, " , "); + val_2_string_from_type_(ReflectionBasicType::Type::Float, float); + break; + case ReflectionBasicType::Type::Float2x2: + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)); + break; + case ReflectionBasicType::Type::Float2x3: + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)); + break; + case ReflectionBasicType::Type::Float2x4: + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)); + break; + case ReflectionBasicType::Type::Float3x2: + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 4)); + break; + case ReflectionBasicType::Type::Float3x3: + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 6)); + break; + case ReflectionBasicType::Type::Float3x4: + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 8)); + break; + case ReflectionBasicType::Type::Float4x2: + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 4)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 6)); + break; + case ReflectionBasicType::Type::Float4x3: + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 6)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 9)); + break; + case ReflectionBasicType::Type::Float4x4: + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 8)).append(",\n"); + asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 12)); + break; + case ReflectionBasicType::Type::Unknown: + default: + break; + } +#undef val_2_string_from_type +#undef val_2_string_from_type_ + + asString.append(" }"); + return asString; + } + + bool ConstantBuffer::guiWidgetForData(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name) + { + std::string displayName = name; + displayName.resize(name.size() + 3, 0); + size_t offset = 0; + unsigned displayIndex = 0; + bool returnValue = false; + + +#define update_array_index_name() displayName[displayName.size() - 3] = '['; \ + displayName[displayName.size() - 2] = '0' + displayIndex; \ + displayName[displayName.size() - 1] = ']'; \ + displayIndex++ +#define concatStrings_(a, b) a##b +#define concatStrings(a, b) concatStrings_(a, b) +#define to_gui_widget(widgetName, baseType) \ + returnValue |= pGui-> concatStrings(add, widgetName)(displayName.c_str(), *reinterpret_cast(data + offset)); \ + offset += sizeof(baseType); + + switch (type) + { + case ReflectionBasicType::Type::Bool4: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + case ReflectionBasicType::Type::Bool3: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + case ReflectionBasicType::Type::Bool2: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + update_array_index_name(); + case ReflectionBasicType::Type::Bool: + to_gui_widget(CheckBox, bool); + break; + case ReflectionBasicType::Type::Uint4: + case ReflectionBasicType::Type::Uint64_4: + case ReflectionBasicType::Type::Int4: + case ReflectionBasicType::Type::Int64_4: + update_array_index_name(); + to_gui_widget(IntVar, int); + case ReflectionBasicType::Type::Uint3: + case ReflectionBasicType::Type::Uint64_3: + case ReflectionBasicType::Type::Int3: + case ReflectionBasicType::Type::Int64_3: + update_array_index_name(); + to_gui_widget(IntVar, int); + case ReflectionBasicType::Type::Uint2: + case ReflectionBasicType::Type::Uint64_2: + case ReflectionBasicType::Type::Int2: + case ReflectionBasicType::Type::Int64_2: + update_array_index_name(); + to_gui_widget(IntVar, int); + update_array_index_name(); + case ReflectionBasicType::Type::Uint: + case ReflectionBasicType::Type::Uint64: + case ReflectionBasicType::Type::Int: + case ReflectionBasicType::Type::Int64: + to_gui_widget(IntVar, int); + break; + case ReflectionBasicType::Type::Float: + returnValue |= pGui->addFloatVar(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float2: + returnValue |= pGui->addFloat2Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float3: + returnValue |= pGui->addFloat3Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float4: + returnValue |= pGui->addFloat4Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float2x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + break; + case ReflectionBasicType::Type::Float2x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); + break; + case ReflectionBasicType::Type::Float2x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + break; + case ReflectionBasicType::Type::Float3x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); + break; + case ReflectionBasicType::Type::Float3x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 6, displayName); + break; + case ReflectionBasicType::Type::Float3x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); + break; + case ReflectionBasicType::Type::Float4x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 6, displayName); + break; + case ReflectionBasicType::Type::Float4x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 3, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 6, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 9, name); + break; + case ReflectionBasicType::Type::Float4x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 12, displayName); + break; + case ReflectionBasicType::Type::Unknown: + break; + default: + break; + } +#undef to_gui_widget +#undef concatStrings +#undef concatStrings_ +#undef update_array_index_name + + return returnValue; + } + + void ConstantBuffer::onGuiRenderMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) + { + // Display reflection data and gather offset + pGui->addText("Name: ", false, textSpacing); + pGui->addText(memberName.c_str(), true, textSpacing + 50.0f); + pGui->addText("Offset: ", false, textSpacing); + pGui->addText(std::to_string(memberOffset).c_str(), true, textSpacing + 50.0f); + pGui->addText(" Size: ", true, textSpacing + 150.0f); + pGui->addText(std::to_string(memberSize).c_str(), true, textSpacing + 200.0f); + pGui->addText(" Type: ", true, textSpacing + 250.0f); + pGui->addText(memberTypeString.c_str(), true, textSpacing + 300.0f); - if (pGui->beginGroup("Constant Buffer")) + // Display data from the stage memory + pGui->addText((val_to_string(memberType, mData.data() + memberOffset)).c_str()); + VariablesBuffer::mDirty |= guiWidgetForData(pGui, memberType, mData.data() + memberOffset, memberName); + + pGui->addSeparator(); + } + + void ConstantBuffer::onGuiRenderInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) + { + static std::unordered_map guiArrayIndices; + + auto memberIt = pStruct->begin(); + while (memberIt != pStruct->end()) + { + size_t numMembers = 1; + size_t memberSize = 0; + ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; + std::string memberName = (*memberIt)->getName(); + constexpr float kTextSpacingOffset = 50.0f; + const ReflectionBasicType* pBasicType = (*memberIt)->getType()->asBasicType(); + ReflectionArrayType* pArrayType = nullptr; + bool baseTypeIsStruct = false; + bool arrayGroupStatus = false; + size_t currentOffset = startOffset + (*memberIt)->getOffset(); + + // First test is not basic type + if (!pBasicType) { - std::string displayString; - for (const auto& reflectionDesc : reflectionDescMap) + // recurse through struct if possible + auto* pStructType = (*memberIt)->getType()->asStructType(); + if (pStructType) { - displayString = "Offset: "; - - displayString.append(std::to_string(offset)); - - displayString.append(" Size: "); - displayString.append(std::to_string(reflectionDesc.first)); + // Iterate through the internal struct + if (pGui->beginGroup(memberName)) + { + memberName.push_back('.'); + onGuiRenderInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); + memberName.pop_back(); - offset += reflectionDesc.first; - - displayString.append(" Type: "); - displayString.append(to_string(reflectionDesc.second.type)); + pGui->endGroup(); + } + pGui->addSeparator(); - displayString.append(" Count: "); - displayString.append(std::to_string(reflectionDesc.second.count)); + // skip to next member + ++memberIt; + continue; + } - pGui->addText(displayString.c_str()); + // if array type gather info for iterating through elements + pArrayType = const_cast((*memberIt)->getType()->asArrayType()); + if (pArrayType) + { pGui->addSeparator(); + + // only iterate through array if it is displaying + arrayGroupStatus = pGui->beginGroup(memberName + "[]"); + if (!arrayGroupStatus) + { + ++memberIt; + pGui->addSeparator(); + continue; + } + + auto* elementBasicType = pArrayType->getType()->asBasicType(); + numMembers = pArrayType->getArraySize(); + memberSize = pArrayType->getArrayStride(); + + if (elementBasicType) + { + memberType = elementBasicType->getType(); + } + else + { + // for special case of array of structures + baseTypeIsStruct = true; + } + + textSpacing += kTextSpacingOffset; + } + else if (!pStructType) + { + // Other types could be presented here + return; + } + } + else + { + // information if only basic type + memberType = pBasicType->getType(); + memberSize = pBasicType->getSize(); + } + + + // Walks through all members in the array + // for (unsigned i = 0; i < numMembers; ++i) + unsigned memberIndex = 0; + + { + std::string displayName = memberName; + if (numMembers > 1) + { + // display information for specific index of array + int32& refGuiArrayIndex = guiArrayIndices[currentStructName + displayName]; + pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), refGuiArrayIndex, 0, static_cast(numMembers) - 1); + memberIndex = refGuiArrayIndex; + currentOffset += (memberSize * memberIndex); + displayName.append("[").append(std::to_string(memberIndex)).append("]"); + } + + if (baseTypeIsStruct) + { + // For arrays of structs, display dropdown for struct before recursing through struct members + if (pGui->beginGroup(displayName)) + { + displayName.push_back('.'); + onGuiRenderInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); + pGui->endGroup(); + } + } + else + { + // for basic types + onGuiRenderMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); } + + currentOffset += memberSize; + } + if (arrayGroupStatus) + { pGui->endGroup(); } + + ++memberIt; + } + } + + void ConstantBuffer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) + { + auto* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); + + if (pGui->beginGroup(std::string("ConstantBuffer").append(mName))) + { + pGui->addSeparator(); + + // begin recursion on first struct + onGuiRenderInternal(pGui, pStruct, "", 0); + + // dirty flag for uploading will be set by GUI + uploadToGPU(); + + pGui->endGroup(); } } } \ No newline at end of file diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index f5aec75a0..7197c7d3a 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -138,11 +138,18 @@ namespace Falcor void onGuiRender(SampleCallbacks* pSample, Gui* pGui); + bool guiWidgetForData(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name); + virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; ConstantBufferView::SharedPtr getCbv() const; + protected: ConstantBuffer(const std::string& name, const ReflectionResourceType::SharedConstPtr& pReflectionType, size_t size); mutable ConstantBufferView::SharedPtr mpCbv; + + private: + void onGuiRenderInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); + void onGuiRenderMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); }; -} \ No newline at end of file +} diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 7b30bf13b..e75defc03 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -276,11 +276,11 @@ namespace Falcor return modified; } - void Gui::addText(const char text[], bool sameLine) - { - if (sameLine) ImGui::SameLine(); - ImGui::Text(text, ""); - } + void Gui::addText(const char text[], bool sameLine, float spacing) + { + if (sameLine) ImGui::SameLine(spacing); + ImGui::Text(text, ""); + } bool Gui::addButton(const char label[], bool sameLine) { diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index b7d94987a..353feb74f 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -90,11 +90,12 @@ namespace Falcor */ bool onKeyboardEvent(const KeyboardEvent& event); - /** Static text - \param[in] text The string to display - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - */ - void addText(const char text[], bool sameLine = false); + /** Static text + \param[in] text The string to display + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \param[in] spacing Optional. Spacing value to the next widget if on the same line + */ + void addText(const char text[], bool sameLine = false, float spacing = -1.0f); /** Button. Will return true if the button was pressed \param[in] label Text to display on the button From f752c4118a72d134e5b197a99661d071c3da6532 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 15 Jun 2018 14:53:25 -0700 Subject: [PATCH 08/36] Adds gui display for constant buffers using the program reflection. --- Framework/Source/Graphics/Program/ProgramReflection.h | 2 -- Samples/ForwardRenderer/ForwardRendererControls.cpp | 3 --- 2 files changed, 5 deletions(-) diff --git a/Framework/Source/Graphics/Program/ProgramReflection.h b/Framework/Source/Graphics/Program/ProgramReflection.h index c8937ac83..986aae995 100644 --- a/Framework/Source/Graphics/Program/ProgramReflection.h +++ b/Framework/Source/Graphics/Program/ProgramReflection.h @@ -392,8 +392,6 @@ namespace Falcor */ const OffsetDesc& getOffsetDesc(size_t offset) const; - const OffsetDescMap& getOffsetDescMap() const { return mOffsetDescMap; } - bool operator==(const ReflectionResourceType& other) const; bool operator==(const ReflectionType& other) const override; private: diff --git a/Samples/ForwardRenderer/ForwardRendererControls.cpp b/Samples/ForwardRenderer/ForwardRendererControls.cpp index c63d3dfc8..392be2f99 100644 --- a/Samples/ForwardRenderer/ForwardRendererControls.cpp +++ b/Samples/ForwardRenderer/ForwardRendererControls.cpp @@ -350,8 +350,5 @@ void ForwardRenderer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) { applyLightingProgramControl(ControlID::EnableHashedAlpha); } - - ConstantBuffer::SharedPtr pCB = mLightingPass.pVars->getConstantBuffer("PerFrameCB"); - pCB->onGuiRender(pSample, pGui); } } From 63747ac44a9098400d8a43c425117c54258bfa6e Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 15 Jun 2018 16:25:59 -0700 Subject: [PATCH 09/36] Changed function name to keep consistancy with other systems --- Framework/Source/API/ConstantBuffer.cpp | 16 ++++++++-------- Framework/Source/API/ConstantBuffer.h | 6 +++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 86219b8b7..6b95c7363 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -346,7 +346,7 @@ namespace Falcor return returnValue; } - void ConstantBuffer::onGuiRenderMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) + void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) { // Display reflection data and gather offset pGui->addText("Name: ", false, textSpacing); @@ -365,7 +365,7 @@ namespace Falcor pGui->addSeparator(); } - void ConstantBuffer::onGuiRenderInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) + void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) { static std::unordered_map guiArrayIndices; @@ -394,7 +394,7 @@ namespace Falcor if (pGui->beginGroup(memberName)) { memberName.push_back('.'); - onGuiRenderInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); + renderUIInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); memberName.pop_back(); pGui->endGroup(); @@ -473,14 +473,14 @@ namespace Falcor if (pGui->beginGroup(displayName)) { displayName.push_back('.'); - onGuiRenderInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); + renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); pGui->endGroup(); } } else { // for basic types - onGuiRenderMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); + renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); } currentOffset += memberSize; @@ -495,16 +495,16 @@ namespace Falcor } } - void ConstantBuffer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) + void ConstantBuffer::renderUI(Gui* pGui) { auto* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); - if (pGui->beginGroup(std::string("ConstantBuffer").append(mName))) + if (pGui->beginGroup(std::string("ConstantBuffer: ").append(mName))) { pGui->addSeparator(); // begin recursion on first struct - onGuiRenderInternal(pGui, pStruct, "", 0); + renderUIInternal(pGui, pStruct, "", 0); // dirty flag for uploading will be set by GUI uploadToGPU(); diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index 7197c7d3a..f8daa2fc9 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -136,7 +136,7 @@ namespace Falcor return VariablesBuffer::setVariableArray(name, 0, pValue, count); } - void onGuiRender(SampleCallbacks* pSample, Gui* pGui); + void renderUI(Gui* pGui); bool guiWidgetForData(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name); @@ -149,7 +149,7 @@ namespace Falcor mutable ConstantBufferView::SharedPtr mpCbv; private: - void onGuiRenderInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); - void onGuiRenderMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); + void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); + void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); }; } From 39fbbeda9100dcb66b772c437ab47e945f4f59de Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 15 Jun 2018 18:50:50 -0700 Subject: [PATCH 10/36] Fixed some of the trivial issues for pull request --- Framework/Source/API/ConstantBuffer.cpp | 716 ++++++++++-------------- Framework/Source/API/ConstantBuffer.h | 34 +- Framework/Source/Utils/Gui.cpp | 10 +- Framework/Source/Utils/Gui.h | 11 +- 4 files changed, 337 insertions(+), 434 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 6b95c7363..91acca1b1 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -88,428 +88,318 @@ namespace Falcor return mpCbv; } - const std::string val_to_string(ReflectionBasicType::Type type, const uint8_t* data) - { - std::string asString("{ "); - size_t offset = 0; - -#define val_2_string_from_type_(typeName, baseType) \ - case typeName: \ - asString.append(std::to_string( *reinterpret_cast(data + offset) )); \ - offset += sizeof(baseType) - -#define val_2_string_from_type(typeName, baseType, endString) \ - val_2_string_from_type_(typeName, baseType); \ - asString.append(endString) - - switch (type) - { - val_2_string_from_type(ReflectionBasicType::Type::Bool4, bool, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Bool3, bool, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Bool2, bool, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Bool, bool); - break; - val_2_string_from_type(ReflectionBasicType::Type::Uint4, uint32_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Uint3, uint32_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Uint2, uint32_t, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Uint, uint32_t); - break; - val_2_string_from_type(ReflectionBasicType::Type::Uint64_4, uint64_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Uint64_3, uint64_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Uint64_2, uint64_t, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Uint64, uint64_t); - break; - val_2_string_from_type(ReflectionBasicType::Type::Int4, int32_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Int3, int32_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Int2, int32_t, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Int, int32_t); - break; - val_2_string_from_type(ReflectionBasicType::Type::Int64_4, int64_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Int64_3, int64_t, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Int64_2, int64_t, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Int64, int64_t); - break; - val_2_string_from_type(ReflectionBasicType::Type::Float4, float, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Float3, float, " , "); - val_2_string_from_type(ReflectionBasicType::Type::Float2, float, " , "); - val_2_string_from_type_(ReflectionBasicType::Type::Float, float); - break; - case ReflectionBasicType::Type::Float2x2: - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)); - break; - case ReflectionBasicType::Type::Float2x3: - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)); - break; - case ReflectionBasicType::Type::Float2x4: - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)); - break; - case ReflectionBasicType::Type::Float3x2: - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 4)); - break; - case ReflectionBasicType::Type::Float3x3: - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 6)); - break; - case ReflectionBasicType::Type::Float3x4: - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 8)); - break; - case ReflectionBasicType::Type::Float4x2: - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 2)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 4)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float2, data + sizeof(float) * 6)); - break; - case ReflectionBasicType::Type::Float4x3: - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 3)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 6)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float3, data + sizeof(float) * 9)); - break; - case ReflectionBasicType::Type::Float4x4: - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 4)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 8)).append(",\n"); - asString.append(val_to_string(ReflectionBasicType::Type::Float4, data + sizeof(float) * 12)); - break; - case ReflectionBasicType::Type::Unknown: - default: - break; - } -#undef val_2_string_from_type -#undef val_2_string_from_type_ - - asString.append(" }"); - return asString; - } - - bool ConstantBuffer::guiWidgetForData(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name) - { - std::string displayName = name; - displayName.resize(name.size() + 3, 0); - size_t offset = 0; - unsigned displayIndex = 0; - bool returnValue = false; + bool ConstantBuffer::getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name) + { + std::string displayName = name; + displayName.resize(name.size() + 3, 0); + size_t offset = 0; + unsigned displayIndex = 0; + bool returnValue = false; #define update_array_index_name() displayName[displayName.size() - 3] = '['; \ - displayName[displayName.size() - 2] = '0' + displayIndex; \ - displayName[displayName.size() - 1] = ']'; \ - displayIndex++ + displayName[displayName.size() - 2] = '0' + displayIndex; \ + displayName[displayName.size() - 1] = ']'; \ + displayIndex++ #define concatStrings_(a, b) a##b #define concatStrings(a, b) concatStrings_(a, b) #define to_gui_widget(widgetName, baseType) \ - returnValue |= pGui-> concatStrings(add, widgetName)(displayName.c_str(), *reinterpret_cast(data + offset)); \ - offset += sizeof(baseType); - - switch (type) - { - case ReflectionBasicType::Type::Bool4: - update_array_index_name(); - to_gui_widget(CheckBox, bool); - case ReflectionBasicType::Type::Bool3: - update_array_index_name(); - to_gui_widget(CheckBox, bool); - case ReflectionBasicType::Type::Bool2: - update_array_index_name(); - to_gui_widget(CheckBox, bool); - update_array_index_name(); - case ReflectionBasicType::Type::Bool: - to_gui_widget(CheckBox, bool); - break; - case ReflectionBasicType::Type::Uint4: - case ReflectionBasicType::Type::Uint64_4: - case ReflectionBasicType::Type::Int4: - case ReflectionBasicType::Type::Int64_4: - update_array_index_name(); - to_gui_widget(IntVar, int); - case ReflectionBasicType::Type::Uint3: - case ReflectionBasicType::Type::Uint64_3: - case ReflectionBasicType::Type::Int3: - case ReflectionBasicType::Type::Int64_3: - update_array_index_name(); - to_gui_widget(IntVar, int); - case ReflectionBasicType::Type::Uint2: - case ReflectionBasicType::Type::Uint64_2: - case ReflectionBasicType::Type::Int2: - case ReflectionBasicType::Type::Int64_2: - update_array_index_name(); - to_gui_widget(IntVar, int); - update_array_index_name(); - case ReflectionBasicType::Type::Uint: - case ReflectionBasicType::Type::Uint64: - case ReflectionBasicType::Type::Int: - case ReflectionBasicType::Type::Int64: - to_gui_widget(IntVar, int); - break; - case ReflectionBasicType::Type::Float: - returnValue |= pGui->addFloatVar(name.c_str(), *reinterpret_cast(data)); - break; - case ReflectionBasicType::Type::Float2: - returnValue |= pGui->addFloat2Var(name.c_str(), *reinterpret_cast(data)); - break; - case ReflectionBasicType::Type::Float3: - returnValue |= pGui->addFloat3Var(name.c_str(), *reinterpret_cast(data)); - break; - case ReflectionBasicType::Type::Float4: - returnValue |= pGui->addFloat4Var(name.c_str(), *reinterpret_cast(data)); - break; - case ReflectionBasicType::Type::Float2x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); - break; - case ReflectionBasicType::Type::Float2x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); - break; - case ReflectionBasicType::Type::Float2x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); - break; - case ReflectionBasicType::Type::Float3x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); - break; - case ReflectionBasicType::Type::Float3x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 6, displayName); - break; - case ReflectionBasicType::Type::Float3x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); - break; - case ReflectionBasicType::Type::Float4x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 6, displayName); - break; - case ReflectionBasicType::Type::Float4x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 3, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 6, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 9, name); - break; - case ReflectionBasicType::Type::Float4x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 12, displayName); - break; - case ReflectionBasicType::Type::Unknown: - break; - default: - break; - } + returnValue |= pGui-> concatStrings(add, widgetName)(displayName.c_str(), *reinterpret_cast(data + offset)); \ + offset += sizeof(baseType); + + switch (type) + { + case ReflectionBasicType::Type::Bool4: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + case ReflectionBasicType::Type::Bool3: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + case ReflectionBasicType::Type::Bool2: + update_array_index_name(); + to_gui_widget(CheckBox, bool); + update_array_index_name(); + case ReflectionBasicType::Type::Bool: + to_gui_widget(CheckBox, bool); + break; + case ReflectionBasicType::Type::Uint4: + case ReflectionBasicType::Type::Uint64_4: + case ReflectionBasicType::Type::Int4: + case ReflectionBasicType::Type::Int64_4: + update_array_index_name(); + to_gui_widget(IntVar, int); + case ReflectionBasicType::Type::Uint3: + case ReflectionBasicType::Type::Uint64_3: + case ReflectionBasicType::Type::Int3: + case ReflectionBasicType::Type::Int64_3: + update_array_index_name(); + to_gui_widget(IntVar, int); + case ReflectionBasicType::Type::Uint2: + case ReflectionBasicType::Type::Uint64_2: + case ReflectionBasicType::Type::Int2: + case ReflectionBasicType::Type::Int64_2: + update_array_index_name(); + to_gui_widget(IntVar, int); + update_array_index_name(); + case ReflectionBasicType::Type::Uint: + case ReflectionBasicType::Type::Uint64: + case ReflectionBasicType::Type::Int: + case ReflectionBasicType::Type::Int64: + to_gui_widget(IntVar, int); + break; + case ReflectionBasicType::Type::Float: + returnValue |= pGui->addFloatVar(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float2: + returnValue |= pGui->addFloat2Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float3: + returnValue |= pGui->addFloat3Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float4: + returnValue |= pGui->addFloat4Var(name.c_str(), *reinterpret_cast(data)); + break; + case ReflectionBasicType::Type::Float2x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + break; + case ReflectionBasicType::Type::Float2x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); + break; + case ReflectionBasicType::Type::Float2x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + break; + case ReflectionBasicType::Type::Float3x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); + break; + case ReflectionBasicType::Type::Float3x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 6, displayName); + break; + case ReflectionBasicType::Type::Float3x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); + break; + case ReflectionBasicType::Type::Float4x2: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 6, displayName); + break; + case ReflectionBasicType::Type::Float4x3: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 3, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 6, name); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 9, name); + break; + case ReflectionBasicType::Type::Float4x4: + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); + update_array_index_name(); + returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 12, displayName); + break; + case ReflectionBasicType::Type::Unknown: + break; + default: + break; + } #undef to_gui_widget #undef concatStrings #undef concatStrings_ #undef update_array_index_name - return returnValue; - } - - void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) - { - // Display reflection data and gather offset - pGui->addText("Name: ", false, textSpacing); - pGui->addText(memberName.c_str(), true, textSpacing + 50.0f); - pGui->addText("Offset: ", false, textSpacing); - pGui->addText(std::to_string(memberOffset).c_str(), true, textSpacing + 50.0f); - pGui->addText(" Size: ", true, textSpacing + 150.0f); - pGui->addText(std::to_string(memberSize).c_str(), true, textSpacing + 200.0f); - pGui->addText(" Type: ", true, textSpacing + 250.0f); - pGui->addText(memberTypeString.c_str(), true, textSpacing + 300.0f); - - // Display data from the stage memory - pGui->addText((val_to_string(memberType, mData.data() + memberOffset)).c_str()); - VariablesBuffer::mDirty |= guiWidgetForData(pGui, memberType, mData.data() + memberOffset, memberName); - - pGui->addSeparator(); - } - - void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) - { - static std::unordered_map guiArrayIndices; - - auto memberIt = pStruct->begin(); - while (memberIt != pStruct->end()) - { - size_t numMembers = 1; - size_t memberSize = 0; - ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; - std::string memberName = (*memberIt)->getName(); - constexpr float kTextSpacingOffset = 50.0f; - const ReflectionBasicType* pBasicType = (*memberIt)->getType()->asBasicType(); - ReflectionArrayType* pArrayType = nullptr; - bool baseTypeIsStruct = false; - bool arrayGroupStatus = false; - size_t currentOffset = startOffset + (*memberIt)->getOffset(); - - // First test is not basic type - if (!pBasicType) - { - // recurse through struct if possible - auto* pStructType = (*memberIt)->getType()->asStructType(); - if (pStructType) - { - // Iterate through the internal struct - if (pGui->beginGroup(memberName)) - { - memberName.push_back('.'); - renderUIInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); - memberName.pop_back(); - - pGui->endGroup(); - } - pGui->addSeparator(); - - // skip to next member - ++memberIt; - continue; - } - - // if array type gather info for iterating through elements - pArrayType = const_cast((*memberIt)->getType()->asArrayType()); - if (pArrayType) - { - pGui->addSeparator(); - - // only iterate through array if it is displaying - arrayGroupStatus = pGui->beginGroup(memberName + "[]"); - if (!arrayGroupStatus) - { - ++memberIt; - pGui->addSeparator(); - continue; - } - - auto* elementBasicType = pArrayType->getType()->asBasicType(); - numMembers = pArrayType->getArraySize(); - memberSize = pArrayType->getArrayStride(); - - if (elementBasicType) - { - memberType = elementBasicType->getType(); - } - else - { - // for special case of array of structures - baseTypeIsStruct = true; - } - - textSpacing += kTextSpacingOffset; - } - else if (!pStructType) - { - // Other types could be presented here - return; - } - } - else - { - // information if only basic type - memberType = pBasicType->getType(); - memberSize = pBasicType->getSize(); - } - - - // Walks through all members in the array - // for (unsigned i = 0; i < numMembers; ++i) - unsigned memberIndex = 0; - - { - std::string displayName = memberName; - if (numMembers > 1) - { - // display information for specific index of array - int32& refGuiArrayIndex = guiArrayIndices[currentStructName + displayName]; - pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), refGuiArrayIndex, 0, static_cast(numMembers) - 1); - memberIndex = refGuiArrayIndex; - currentOffset += (memberSize * memberIndex); - displayName.append("[").append(std::to_string(memberIndex)).append("]"); - } - - if (baseTypeIsStruct) - { - // For arrays of structs, display dropdown for struct before recursing through struct members - if (pGui->beginGroup(displayName)) - { - displayName.push_back('.'); - renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); - pGui->endGroup(); - } - } - else - { - // for basic types - renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); - } - - currentOffset += memberSize; - } - - if (arrayGroupStatus) - { - pGui->endGroup(); - } - - ++memberIt; - } - } - - void ConstantBuffer::renderUI(Gui* pGui) - { - auto* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); - - if (pGui->beginGroup(std::string("ConstantBuffer: ").append(mName))) - { - pGui->addSeparator(); - - // begin recursion on first struct - renderUIInternal(pGui, pStruct, "", 0); - - // dirty flag for uploading will be set by GUI - uploadToGPU(); - - pGui->endGroup(); - } - } + return returnValue; + } + + void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) + { + // Display reflection data and gather offset + pGui->addText("Name: ", false); + pGui->addText(memberName.c_str(), true); //, textSpacing + 50.0f + pGui->addText("Offset: ", false); // textSpacing + pGui->addText(std::to_string(memberOffset).c_str(), true); //textSpacing + 50.0f + pGui->addText(" Size: ", true); // textSpacing + 150.0f + pGui->addText(std::to_string(memberSize).c_str(), true); // textSpacing + 200.0f + pGui->addText(" Type: ", true); // textSpacing + 250.0f + pGui->addText(memberTypeString.c_str(), true); // textSpacing + 300.0f + + // Display data from the stage memory + mDirty |= guiWidgetForData(pGui, memberType, mData.data() + memberOffset, memberName); + + pGui->addSeparator(); + } + + void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) + { + static std::unordered_map guiArrayIndices; + + for (auto memberIt = pStruct->begin(); memberIt != pStruct->end(); ++memberIt) + { + size_t numMembers = 1; + size_t memberSize = 0; + ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; + std::string memberName = (*memberIt)->getName(); + constexpr float kTextSpacingOffset = 50.0f; + const ReflectionBasicType* pBasicType = (*memberIt)->getType()->asBasicType(); + ReflectionArrayType* pArrayType = nullptr; + bool baseTypeIsStruct = false; + bool arrayGroupStatus = false; + size_t currentOffset = startOffset + (*memberIt)->getOffset(); + + // First test is not basic type + if (!pBasicType) + { + // recurse through struct if possible + auto* pStructType = (*memberIt)->getType()->asStructType(); + if (pStructType) + { + // Iterate through the internal struct + if (pGui->beginGroup(memberName)) + { + memberName.push_back('.'); + renderUIInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); + memberName.pop_back(); + + pGui->endGroup(); + } + pGui->addSeparator(); + + // skip to next member + continue; + } + + // if array type gather info for iterating through elements + pArrayType = const_cast((*memberIt)->getType()->asArrayType()); + if (pArrayType) + { + pGui->addSeparator(); + + // only iterate through array if it is displaying + arrayGroupStatus = pGui->beginGroup(memberName + "[]"); + if (!arrayGroupStatus) + { + pGui->addSeparator(); + continue; + } + + auto* elementBasicType = pArrayType->getType()->asBasicType(); + numMembers = pArrayType->getArraySize(); + memberSize = pArrayType->getArrayStride(); + + if (elementBasicType) + { + memberType = elementBasicType->getType(); + } + else + { + // for special case of array of structures + baseTypeIsStruct = true; + } + + textSpacing += kTextSpacingOffset; + } + else if (!pStructType) + { + // Other types could be presented here + return; + } + } + else + { + // information if only basic type + memberType = pBasicType->getType(); + memberSize = pBasicType->getSize(); + } + + + // Display member of the array + unsigned memberIndex = 0; + std::string displayName = memberName; + + if (numMembers > 1) + { + // display information for specific index of array + int32& refGuiArrayIndex = guiArrayIndices[currentStructName + displayName]; + pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), refGuiArrayIndex, 0, static_cast(numMembers) - 1); + memberIndex = refGuiArrayIndex; + currentOffset += (memberSize * memberIndex); + displayName.append("[").append(std::to_string(memberIndex)).append("]"); + } + + if (baseTypeIsStruct) + { + // For arrays of structs, display dropdown for struct before recursing through struct members + if (pGui->beginGroup(displayName)) + { + displayName.push_back('.'); + renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); + pGui->endGroup(); + } + } + else + { + // for basic types + renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); + } + + currentOffset += memberSize; + + + if (arrayGroupStatus) + { + pGui->endGroup(); + } + } + } + + void ConstantBuffer::renderUI(Gui* pGui) + { + auto* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); + + if (pGui->beginGroup(std::string("ConstantBuffer: ").append(mName))) + { + pGui->addSeparator(); + + // begin recursion on first struct + renderUIInternal(pGui, pStruct, "", 0); + + // dirty flag for uploading will be set by GUI + uploadToGPU(); + + pGui->endGroup(); + } + } } \ No newline at end of file diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index f8daa2fc9..e4c751f3b 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -35,9 +35,9 @@ namespace Falcor { class Sampler; - // Forward declares for gui draw func - class SampleCallbacks; - class Gui; + // Forward declares for gui draw func + class SampleCallbacks; + class Gui; /** Abstracts a Constant/Uniform buffer. When accessing a variable by name, you can only use a name which points to a basic Type, or an array of basic Type (so if you want the start of a structure, ask for the first field in the struct). @@ -136,20 +136,34 @@ namespace Falcor return VariablesBuffer::setVariableArray(name, 0, pValue, count); } - void renderUI(Gui* pGui); - - bool guiWidgetForData(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name); + void renderUI(Gui* pGui); + virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; ConstantBufferView::SharedPtr getCbv() const; - protected: + private: ConstantBuffer(const std::string& name, const ReflectionResourceType::SharedConstPtr& pReflectionType, size_t size); mutable ConstantBufferView::SharedPtr mpCbv; - private: - void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); - void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); + /** Render gui widget for reflected data + \param[in] pGui Pointer to the gui structure for rendering + \param[in] type Reflection type to look up corresponding widget + \param[in] name String name for widget to display + */ + bool getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name); + + /** Render gui widget for reflected data + \param[in] pGui Pointer to the gui structure for rendering + \param[in] type Reflection type to look up corresponding widget + \param[in] name String name for widget to display + */ + void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); + + /** + + */ + void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); }; } diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 499f33564..62c96d346 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -276,11 +276,11 @@ namespace Falcor return modified; } - void Gui::addText(const char text[], bool sameLine, float spacing) - { - if (sameLine) ImGui::SameLine(spacing); - ImGui::Text(text, ""); - } + void Gui::addText(const char text[], bool sameLine) + { + if (sameLine) ImGui::SameLine(); + ImGui::Text(text, ""); + } bool Gui::addButton(const char label[], bool sameLine) { diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 353feb74f..b7d94987a 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -90,12 +90,11 @@ namespace Falcor */ bool onKeyboardEvent(const KeyboardEvent& event); - /** Static text - \param[in] text The string to display - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \param[in] spacing Optional. Spacing value to the next widget if on the same line - */ - void addText(const char text[], bool sameLine = false, float spacing = -1.0f); + /** Static text + \param[in] text The string to display + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + */ + void addText(const char text[], bool sameLine = false); /** Button. Will return true if the button was pressed \param[in] label Text to display on the button From cbd5078743e062d505f8769cfca4cadaeaaa9d43 Mon Sep 17 00:00:00 2001 From: Pierre Moreau Date: Mon, 18 Jun 2018 22:36:14 +0200 Subject: [PATCH 11/36] Do not catch polymorphic types by value --- Framework/Source/ArgList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Source/ArgList.cpp b/Framework/Source/ArgList.cpp index b8f7c6177..c20ec9faa 100644 --- a/Framework/Source/ArgList.cpp +++ b/Framework/Source/ArgList.cpp @@ -73,7 +73,7 @@ namespace Falcor { return mMap.at(key); } - catch(std::out_of_range) + catch(const std::out_of_range&) { return std::vector(); } From 5097aaf7733bc7819ec0a5dcb9fe997ce4c0cb8c Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 18 Jun 2018 15:10:30 -0700 Subject: [PATCH 12/36] Fixed other issues from pull request. Add gui functions for matrices, int vecs, and bool vecs. --- Framework/Source/API/ConstantBuffer.cpp | 154 ++++++++---------------- Framework/Source/API/ConstantBuffer.h | 29 +++-- Framework/Source/Utils/Gui.cpp | 86 +++++++++++++ Framework/Source/Utils/Gui.h | 91 ++++++++++++++ 4 files changed, 244 insertions(+), 116 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 91acca1b1..def46d417 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -88,37 +88,28 @@ namespace Falcor return mpCbv; } - bool ConstantBuffer::getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name) + bool ConstantBuffer::getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) { - std::string displayName = name; - displayName.resize(name.size() + 3, 0); - size_t offset = 0; unsigned displayIndex = 0; bool returnValue = false; - -#define update_array_index_name() displayName[displayName.size() - 3] = '['; \ - displayName[displayName.size() - 2] = '0' + displayIndex; \ - displayName[displayName.size() - 1] = ']'; \ - displayIndex++ #define concatStrings_(a, b) a##b #define concatStrings(a, b) concatStrings_(a, b) #define to_gui_widget(widgetName, baseType) \ - returnValue |= pGui-> concatStrings(add, widgetName)(displayName.c_str(), *reinterpret_cast(data + offset)); \ + returnValue |= pGui-> concatStrings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ offset += sizeof(baseType); switch (type) { case ReflectionBasicType::Type::Bool4: - update_array_index_name(); - to_gui_widget(CheckBox, bool); + to_gui_widget(Bool4Var, glm::bvec4); + break; case ReflectionBasicType::Type::Bool3: - update_array_index_name(); - to_gui_widget(CheckBox, bool); + to_gui_widget(Bool3Var, glm::bvec3); + break; case ReflectionBasicType::Type::Bool2: - update_array_index_name(); - to_gui_widget(CheckBox, bool); - update_array_index_name(); + to_gui_widget(Bool2Var, glm::bvec2); + break; case ReflectionBasicType::Type::Bool: to_gui_widget(CheckBox, bool); break; @@ -126,21 +117,20 @@ namespace Falcor case ReflectionBasicType::Type::Uint64_4: case ReflectionBasicType::Type::Int4: case ReflectionBasicType::Type::Int64_4: - update_array_index_name(); - to_gui_widget(IntVar, int); + to_gui_widget(Int4Var, glm::ivec4); + break; case ReflectionBasicType::Type::Uint3: case ReflectionBasicType::Type::Uint64_3: case ReflectionBasicType::Type::Int3: case ReflectionBasicType::Type::Int64_3: - update_array_index_name(); - to_gui_widget(IntVar, int); + to_gui_widget(Int3Var, glm::ivec3); + break; case ReflectionBasicType::Type::Uint2: case ReflectionBasicType::Type::Uint64_2: case ReflectionBasicType::Type::Int2: case ReflectionBasicType::Type::Int64_2: - update_array_index_name(); - to_gui_widget(IntVar, int); - update_array_index_name(); + to_gui_widget(Int2Var, glm::ivec2); + break; case ReflectionBasicType::Type::Uint: case ReflectionBasicType::Type::Uint64: case ReflectionBasicType::Type::Int: @@ -148,88 +138,43 @@ namespace Falcor to_gui_widget(IntVar, int); break; case ReflectionBasicType::Type::Float: - returnValue |= pGui->addFloatVar(name.c_str(), *reinterpret_cast(data)); + to_gui_widget(FloatVar, float); break; case ReflectionBasicType::Type::Float2: - returnValue |= pGui->addFloat2Var(name.c_str(), *reinterpret_cast(data)); + to_gui_widget(Float2Var, glm::vec2); break; case ReflectionBasicType::Type::Float3: - returnValue |= pGui->addFloat3Var(name.c_str(), *reinterpret_cast(data)); + to_gui_widget(Float3Var, glm::vec3); break; case ReflectionBasicType::Type::Float4: - returnValue |= pGui->addFloat4Var(name.c_str(), *reinterpret_cast(data)); + to_gui_widget(Float4Var, glm::vec4); break; case ReflectionBasicType::Type::Float2x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); + to_gui_widget(Matrix2x2Var, glm::mat2x2); break; case ReflectionBasicType::Type::Float2x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); + to_gui_widget(Matrix2x3Var, glm::mat2x3); break; case ReflectionBasicType::Type::Float2x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); + to_gui_widget(Matrix2x4Var, glm::mat2x4); break; case ReflectionBasicType::Type::Float3x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); + to_gui_widget(Matrix3x2Var, glm::mat3x2); break; case ReflectionBasicType::Type::Float3x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 3, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float3, data + sizeof(float) * 6, displayName); + to_gui_widget(Matrix3x3Var, glm::mat3x3); break; case ReflectionBasicType::Type::Float3x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); + to_gui_widget(Matrix3x4Var, glm::mat3x4); break; case ReflectionBasicType::Type::Float4x2: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 2, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float2, data + sizeof(float) * 6, displayName); + to_gui_widget(Matrix4x2Var, glm::mat4x2); break; case ReflectionBasicType::Type::Float4x3: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 3, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 6, name); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 9, name); + to_gui_widget(Matrix4x3Var, glm::mat4x3); break; case ReflectionBasicType::Type::Float4x4: - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 4, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 8, displayName); - update_array_index_name(); - returnValue |= guiWidgetForData(pGui, ReflectionBasicType::Type::Float4, data + sizeof(float) * 12, displayName); + to_gui_widget(Matrix4x4Var, glm::mat4x4); break; case ReflectionBasicType::Type::Unknown: break; @@ -239,32 +184,31 @@ namespace Falcor #undef to_gui_widget #undef concatStrings #undef concatStrings_ -#undef update_array_index_name return returnValue; } - void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing) + void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType) { // Display reflection data and gather offset pGui->addText("Name: ", false); - pGui->addText(memberName.c_str(), true); //, textSpacing + 50.0f - pGui->addText("Offset: ", false); // textSpacing - pGui->addText(std::to_string(memberOffset).c_str(), true); //textSpacing + 50.0f - pGui->addText(" Size: ", true); // textSpacing + 150.0f - pGui->addText(std::to_string(memberSize).c_str(), true); // textSpacing + 200.0f - pGui->addText(" Type: ", true); // textSpacing + 250.0f - pGui->addText(memberTypeString.c_str(), true); // textSpacing + 300.0f + pGui->addText(memberName.c_str(), true); + pGui->addText("Offset: ", false); + pGui->addText(std::to_string(memberOffset).c_str(), true); + pGui->addText(" Size: ", true); + pGui->addText(std::to_string(memberSize).c_str(), true); + pGui->addText(" Type: ", true); + pGui->addText(memberTypeString.c_str(), true); // Display data from the stage memory - mDirty |= guiWidgetForData(pGui, memberType, mData.data() + memberOffset, memberName); + mDirty |= getGuiWidgetFromType(pGui, memberType, memberOffset, memberName); pGui->addSeparator(); } - void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float textSpacing) + void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset) { - static std::unordered_map guiArrayIndices; + static std::unordered_map sGuiArrayIndices; for (auto memberIt = pStruct->begin(); memberIt != pStruct->end(); ++memberIt) { @@ -272,9 +216,8 @@ namespace Falcor size_t memberSize = 0; ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; std::string memberName = (*memberIt)->getName(); - constexpr float kTextSpacingOffset = 50.0f; const ReflectionBasicType* pBasicType = (*memberIt)->getType()->asBasicType(); - ReflectionArrayType* pArrayType = nullptr; + const ReflectionArrayType* pArrayType = nullptr; bool baseTypeIsStruct = false; bool arrayGroupStatus = false; size_t currentOffset = startOffset + (*memberIt)->getOffset(); @@ -283,14 +226,14 @@ namespace Falcor if (!pBasicType) { // recurse through struct if possible - auto* pStructType = (*memberIt)->getType()->asStructType(); + const ReflectionStructType* pStructType = (*memberIt)->getType()->asStructType(); if (pStructType) { // Iterate through the internal struct if (pGui->beginGroup(memberName)) { memberName.push_back('.'); - renderUIInternal(pGui, pStructType, memberName, currentOffset, textSpacing + kTextSpacingOffset); + renderUIInternal(pGui, pStructType, memberName, currentOffset); memberName.pop_back(); pGui->endGroup(); @@ -302,7 +245,8 @@ namespace Falcor } // if array type gather info for iterating through elements - pArrayType = const_cast((*memberIt)->getType()->asArrayType()); + pArrayType = (*memberIt)->getType()->asArrayType(); + if (pArrayType) { pGui->addSeparator(); @@ -315,7 +259,7 @@ namespace Falcor continue; } - auto* elementBasicType = pArrayType->getType()->asBasicType(); + const ReflectionBasicType* elementBasicType = pArrayType->getType()->asBasicType(); numMembers = pArrayType->getArraySize(); memberSize = pArrayType->getArrayStride(); @@ -328,8 +272,6 @@ namespace Falcor // for special case of array of structures baseTypeIsStruct = true; } - - textSpacing += kTextSpacingOffset; } else if (!pStructType) { @@ -352,7 +294,7 @@ namespace Falcor if (numMembers > 1) { // display information for specific index of array - int32& refGuiArrayIndex = guiArrayIndices[currentStructName + displayName]; + int32& refGuiArrayIndex = sGuiArrayIndices[currentStructName + displayName]; pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), refGuiArrayIndex, 0, static_cast(numMembers) - 1); memberIndex = refGuiArrayIndex; currentOffset += (memberSize * memberIndex); @@ -365,14 +307,14 @@ namespace Falcor if (pGui->beginGroup(displayName)) { displayName.push_back('.'); - renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, textSpacing + kTextSpacingOffset); + renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset); pGui->endGroup(); } } else { // for basic types - renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, textSpacing); + renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType); } currentOffset += memberSize; @@ -387,7 +329,7 @@ namespace Falcor void ConstantBuffer::renderUI(Gui* pGui) { - auto* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); + const ReflectionStructType* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); if (pGui->beginGroup(std::string("ConstantBuffer: ").append(mName))) { diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index e4c751f3b..b542e3b89 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -136,9 +136,11 @@ namespace Falcor return VariablesBuffer::setVariableArray(name, 0, pValue, count); } + /** Renders ui for reflected data within the buffer. + \param[in] pGui Pointer to the gui structure for rendering + */ void renderUI(Gui* pGui); - virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; ConstantBufferView::SharedPtr getCbv() const; @@ -147,23 +149,30 @@ namespace Falcor ConstantBuffer(const std::string& name, const ReflectionResourceType::SharedConstPtr& pReflectionType, size_t size); mutable ConstantBufferView::SharedPtr mpCbv; - /** Render gui widget for reflected data + /** Call the corresponding gui function using the reflected data \param[in] pGui Pointer to the gui structure for rendering \param[in] type Reflection type to look up corresponding widget + \param[in] offset offset into the data array of the constant buffer \param[in] name String name for widget to display + \return true if data was changed from the widget. internal used to call upload to gpu */ - bool getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, uint8_t* data, const std::string& name); + bool getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); - /** Render gui widget for reflected data + /** Recursive function for traversing reflection data and display ui \param[in] pGui Pointer to the gui structure for rendering - \param[in] type Reflection type to look up corresponding widget - \param[in] name String name for widget to display + \param[in] pStruct Pointer to structure to iterate and display for the gui + \param[in] currentStructName Current struct name to append for full reflection name + \param[in] startOffset Starting offset in memory for nested structures */ - void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, float spacing = 0.0f); + void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset); - /** - + /** Render gui widget for reflected data + \param[in] pGui Pointer to the gui structure for rendering + \param[in] memberName string containing the name of the data member to render + \param[in] memberOffset offset into the data array + \param[in] memberSize size of the data in the member + \param[in] memberType reflection type enum for the basic type */ - void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, float textSpacing); + void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType); }; } diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 62c96d346..006d0c39c 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -276,6 +276,36 @@ namespace Falcor return modified; } + bool Gui::addBool2Var(const char label[], glm::bvec2& var, bool sameLine) + { + return addNCheckboxes(label, glm::value_ptr(var), 2, sameLine); + } + + bool Gui::addBool3Var(const char label[], glm::bvec3& var, bool sameLine) + { + return addNCheckboxes(label, glm::value_ptr(var), 3, sameLine); + } + + bool Gui::addBool4Var(const char label[], glm::bvec4& var, bool sameLine) + { + return addNCheckboxes(label, glm::value_ptr(var), 4, sameLine); + } + + bool Gui::addNCheckboxes(const char label[], bool* pData, int numCheckboxes, bool sameLine) + { + bool modified = false; + std::string labelString(label); + labelString.append("[0]"); + + for (int i = 0; i < numCheckboxes; ++i) + { + labelString[labelString.size() - 2] = '0' + i; + modified |= addCheckBox(labelString.c_str(), pData[i], sameLine); + } + + return modified; + } + void Gui::addText(const char text[], bool sameLine) { if (sameLine) ImGui::SameLine(); @@ -365,6 +395,62 @@ namespace Falcor return b; } + bool Gui::addInt2Var(const char label[], glm::ivec2& var, int minVal, int maxVal, bool sameLine) + { + if (sameLine) ImGui::SameLine(); + bool b = ImGui::InputInt2(label, static_cast(glm::value_ptr(var)), 0); + var = clamp(var, minVal, maxVal); + return b; + } + + bool Gui::addInt3Var(const char label[], glm::ivec3& var, int minVal, int maxVal, bool sameLine) + { + if (sameLine) ImGui::SameLine(); + bool b = ImGui::InputInt3(label, static_cast(glm::value_ptr(var)), 0); + var = clamp(var, minVal, maxVal); + return b; + } + + bool Gui::addInt4Var(const char label[], glm::ivec4& var, int minVal, int maxVal, bool sameLine) + { + if (sameLine) ImGui::SameLine(); + bool b = ImGui::InputInt4(label, static_cast(glm::value_ptr(var)), 0); + var = clamp(var, minVal, maxVal); + return b; + } + +#define concatStrings_(a, b) a##b +#define concatStrings(a, b) concatStrings_(a, b) +#define add_matrix_function(funcName, matrixSize, baseFunc) \ + bool concatStrings(Gui::, funcName) (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ + { \ + std::string labelString(label); \ + labelString.append("[0]"); \ + bool b = false; \ + \ + for (int i = 0; i < var.length(); ++i) \ + { \ + labelString[labelString.size() - 2] = '0' + i; \ + b |= baseFunc (labelString.c_str(), var[i], minVal, maxVal, sameLine); \ + } \ + \ + return b;\ + } + + add_matrix_function(addMatrix2x2Var, 2x2, addFloat2Var) + add_matrix_function(addMatrix2x3Var, 2x3, addFloat3Var) + add_matrix_function(addMatrix2x4Var, 2x4, addFloat4Var) + add_matrix_function(addMatrix3x2Var, 3x2, addFloat2Var) + add_matrix_function(addMatrix3x3Var, 3x3, addFloat3Var) + add_matrix_function(addMatrix3x4Var, 3x4, addFloat4Var) + add_matrix_function(addMatrix4x2Var, 4x2, addFloat2Var) + add_matrix_function(addMatrix4x3Var, 4x3, addFloat3Var) + add_matrix_function(addMatrix4x4Var, 4x4, addFloat4Var) + +#undef add_matrix_function +#undef concatStrings +#undef concatStrings_ + bool Gui::addRgbColor(const char label[], glm::vec3& var, bool sameLine) { if (sameLine) ImGui::SameLine(); diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index b7d94987a..06501ab3e 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -179,6 +179,39 @@ namespace Falcor */ bool addCheckBox(const char label[], int& pVar, bool sameLine = false); + /** Adds a checkbox. + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addBool2Var(const char lable[], glm::bvec2& var, bool sameLine = false); + + /** Adds a checkbox. + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addBool3Var(const char lable[], glm::bvec3& var, bool sameLine = false); + + /** Adds a checkbox. + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addBool4Var(const char lable[], glm::bvec4& var, bool sameLine = false); + + /** Adds a checkbox. + \param[in] label The name of the checkbox. + \param[in] var Pointer to the array of bools to fill checkboxes for + \param[in] numCheckboxes number of checkbox widgets to create for same number of bools + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addNCheckboxes(const char label[], bool* pData, int numCheckboxes, bool sameLine); + /** Adds an RGB color UI widget. \param[in] label The name of the widget. \param[in] var A reference to a vector that will be updated directly when the widget state changes. @@ -206,6 +239,64 @@ namespace Falcor */ bool addIntVar(const char label[], int32_t& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, int step = 1, bool sameLine = false); + /** Adds an integer UI widget. + \param[in] label The name of the widget. + \param[in] var A reference to two integers that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addInt2Var(const char label[], glm::ivec2& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + + /** Adds an integer UI widget. + \param[in] label The name of the widget. + \param[in] var A reference to a vector of 3 integers that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addInt3Var(const char label[], glm::ivec3& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + + /** Adds an integer UI widget. + \param[in] label The name of the widget. + \param[in] var A reference to a vector of 4 integers that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ + bool addInt4Var(const char label[], glm::ivec4& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + + /** Adds an matrix UI widget. + \param[in] label The name of the widget. + \param[in] var A reference to the matrix struct that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false + */ +#define concatStrings_(a, b) a##b +#define concatStrings(a, b) concatStrings_(a, b) +#define add_matrix_function(funcName, matrixSize) \ + bool funcName (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal = -1, float maxVal = 1, bool sameLine = false) + + add_matrix_function(addMatrix2x2Var, 2x2); + add_matrix_function(addMatrix2x3Var, 2x3); + add_matrix_function(addMatrix2x4Var, 2x4); + add_matrix_function(addMatrix3x2Var, 3x2); + add_matrix_function(addMatrix3x3Var, 3x3); + add_matrix_function(addMatrix3x4Var, 3x4); + add_matrix_function(addMatrix4x2Var, 4x2); + add_matrix_function(addMatrix4x3Var, 4x3); + add_matrix_function(addMatrix4x4Var, 4x4); + +#undef add_matrix_function +#undef concatStrings +#undef concatStrings_ + + /** Add a separator */ void addSeparator(); From 599f65a7582750379501ae74565d9b68a208ba25 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 18 Jun 2018 19:13:29 -0700 Subject: [PATCH 13/36] Fixed other issues from pull request. Add gui functions for matrices, int vecs, and bool vecs. --- Framework/Source/API/ConstantBuffer.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index def46d417..6972052d9 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -35,9 +35,7 @@ #include "API/Device.h" #include "Renderer.h" -#include "utils/Gui.h" - - +#include "Utils/Gui.h" namespace Falcor { From 0c38df1d2993ced7eb92a5ebdd564250578824cd Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Tue, 26 Jun 2018 17:09:34 -0700 Subject: [PATCH 14/36] Fixed remaining issues with pull request --- Framework/Source/API/ConstantBuffer.cpp | 16 ++--- Framework/Source/API/ConstantBuffer.h | 2 +- Framework/Source/Utils/Gui.cpp | 16 ++--- Framework/Source/Utils/Gui.h | 78 ++++++++++++------------- 4 files changed, 56 insertions(+), 56 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 6972052d9..aa0fb622f 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -86,7 +86,7 @@ namespace Falcor return mpCbv; } - bool ConstantBuffer::getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) + bool ConstantBuffer::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) { unsigned displayIndex = 0; bool returnValue = false; @@ -94,7 +94,7 @@ namespace Falcor #define concatStrings_(a, b) a##b #define concatStrings(a, b) concatStrings_(a, b) #define to_gui_widget(widgetName, baseType) \ - returnValue |= pGui-> concatStrings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ + returnValue = pGui-> concatStrings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ offset += sizeof(baseType); switch (type) @@ -177,6 +177,7 @@ namespace Falcor case ReflectionBasicType::Type::Unknown: break; default: + should_not_get_here(); break; } #undef to_gui_widget @@ -199,14 +200,14 @@ namespace Falcor pGui->addText(memberTypeString.c_str(), true); // Display data from the stage memory - mDirty |= getGuiWidgetFromType(pGui, memberType, memberOffset, memberName); + mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName); pGui->addSeparator(); } void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset) { - static std::unordered_map sGuiArrayIndices; + static std::unordered_map sGuiArrayIndices; for (auto memberIt = pStruct->begin(); memberIt != pStruct->end(); ++memberIt) { @@ -286,15 +287,14 @@ namespace Falcor // Display member of the array - unsigned memberIndex = 0; + int32_t memberIndex = 0; std::string displayName = memberName; if (numMembers > 1) { // display information for specific index of array - int32& refGuiArrayIndex = sGuiArrayIndices[currentStructName + displayName]; - pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), refGuiArrayIndex, 0, static_cast(numMembers) - 1); - memberIndex = refGuiArrayIndex; + memberIndex = sGuiArrayIndices[displayName]; + pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), memberIndex, 0, static_cast(numMembers) - 1); currentOffset += (memberSize * memberIndex); displayName.append("[").append(std::to_string(memberIndex)).append("]"); } diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index b542e3b89..8f523b06f 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -156,7 +156,7 @@ namespace Falcor \param[in] name String name for widget to display \return true if data was changed from the widget. internal used to call upload to gpu */ - bool getGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); + bool renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); /** Recursive function for traversing reflection data and display ui \param[in] pGui Pointer to the gui structure for rendering diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 006d0c39c..b899d7172 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -291,15 +291,15 @@ namespace Falcor return addNCheckboxes(label, glm::value_ptr(var), 4, sameLine); } - bool Gui::addNCheckboxes(const char label[], bool* pData, int numCheckboxes, bool sameLine) + bool Gui::addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) { bool modified = false; std::string labelString(label); labelString.append("[0]"); - for (int i = 0; i < numCheckboxes; ++i) + for (uint32_t i = 0; i < numCheckboxes; ++i) { - labelString[labelString.size() - 2] = '0' + i; + labelString[labelString.size() - 2] = '0' + static_cast(i); modified |= addCheckBox(labelString.c_str(), pData[i], sameLine); } @@ -395,7 +395,7 @@ namespace Falcor return b; } - bool Gui::addInt2Var(const char label[], glm::ivec2& var, int minVal, int maxVal, bool sameLine) + bool Gui::addInt2Var(const char label[], glm::ivec2& var, int32_t minVal, int32_t maxVal, bool sameLine) { if (sameLine) ImGui::SameLine(); bool b = ImGui::InputInt2(label, static_cast(glm::value_ptr(var)), 0); @@ -403,7 +403,7 @@ namespace Falcor return b; } - bool Gui::addInt3Var(const char label[], glm::ivec3& var, int minVal, int maxVal, bool sameLine) + bool Gui::addInt3Var(const char label[], glm::ivec3& var, int32_t minVal, int32_t maxVal, bool sameLine) { if (sameLine) ImGui::SameLine(); bool b = ImGui::InputInt3(label, static_cast(glm::value_ptr(var)), 0); @@ -411,7 +411,7 @@ namespace Falcor return b; } - bool Gui::addInt4Var(const char label[], glm::ivec4& var, int minVal, int maxVal, bool sameLine) + bool Gui::addInt4Var(const char label[], glm::ivec4& var, int32_t minVal, int32_t maxVal, bool sameLine) { if (sameLine) ImGui::SameLine(); bool b = ImGui::InputInt4(label, static_cast(glm::value_ptr(var)), 0); @@ -428,9 +428,9 @@ namespace Falcor labelString.append("[0]"); \ bool b = false; \ \ - for (int i = 0; i < var.length(); ++i) \ + for (uint32_t i = 0; i < static_cast(var.length()); ++i) \ { \ - labelString[labelString.size() - 2] = '0' + i; \ + labelString[labelString.size() - 2] = '0' + static_cast(i); \ b |= baseFunc (labelString.c_str(), var[i], minVal, maxVal, sameLine); \ } \ \ diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 06501ab3e..43edc0eff 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -180,37 +180,37 @@ namespace Falcor bool addCheckBox(const char label[], int& pVar, bool sameLine = false); /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ bool addBool2Var(const char lable[], glm::bvec2& var, bool sameLine = false); /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ bool addBool3Var(const char lable[], glm::bvec3& var, bool sameLine = false); /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the checkbox. + \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ bool addBool4Var(const char lable[], glm::bvec4& var, bool sameLine = false); /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var Pointer to the array of bools to fill checkboxes for - \param[in] numCheckboxes number of checkbox widgets to create for same number of bools - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the checkbox. + \param[in] var Pointer to the array of bools to fill checkboxes for + \param[in] numCheckboxes number of checkbox widgets to create for same number of bools + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ - bool addNCheckboxes(const char label[], bool* pData, int numCheckboxes, bool sameLine); + bool addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); /** Adds an RGB color UI widget. \param[in] label The name of the widget. @@ -247,35 +247,35 @@ namespace Falcor \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ - bool addInt2Var(const char label[], glm::ivec2& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + bool addInt2Var(const char label[], glm::ivec2& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 3 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the widget. + \param[in] var A reference to a vector of 3 integers that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ - bool addInt3Var(const char label[], glm::ivec3& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + bool addInt3Var(const char label[], glm::ivec3& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 4 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the widget. + \param[in] var A reference to a vector of 4 integers that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ - bool addInt4Var(const char label[], glm::ivec4& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, bool sameLine = false); + bool addInt4Var(const char label[], glm::ivec4& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); /** Adds an matrix UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to the matrix struct that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false + \param[in] label The name of the widget. + \param[in] var A reference to the matrix struct that will be updated directly when the widget state changes. + \param[in] minVal Optional. The minimum allowed value for the variable. + \param[in] maxVal Optional. The maximum allowed value for the variable. + \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget + \return true if the value changed, otherwise false */ #define concatStrings_(a, b) a##b #define concatStrings(a, b) concatStrings_(a, b) From cf32e211d10bb054ca3c886f5b2448eb519991ae Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Tue, 26 Jun 2018 17:14:54 -0700 Subject: [PATCH 15/36] Fixed remaining issues with pull request --- Framework/Source/API/ConstantBuffer.cpp | 4 +--- Framework/Source/API/ConstantBuffer.h | 2 ++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index aa0fb622f..50f4cca7f 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -207,8 +207,6 @@ namespace Falcor void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset) { - static std::unordered_map sGuiArrayIndices; - for (auto memberIt = pStruct->begin(); memberIt != pStruct->end(); ++memberIt) { size_t numMembers = 1; @@ -293,7 +291,7 @@ namespace Falcor if (numMembers > 1) { // display information for specific index of array - memberIndex = sGuiArrayIndices[displayName]; + memberIndex = mGuiArrayIndices[displayName]; pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), memberIndex, 0, static_cast(numMembers) - 1); currentOffset += (memberSize * memberIndex); displayName.append("[").append(std::to_string(memberIndex)).append("]"); diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index 8f523b06f..2c00cc43d 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -149,6 +149,8 @@ namespace Falcor ConstantBuffer(const std::string& name, const ReflectionResourceType::SharedConstPtr& pReflectionType, size_t size); mutable ConstantBufferView::SharedPtr mpCbv; + std::unordered_map mGuiArrayIndices; + /** Call the corresponding gui function using the reflected data \param[in] pGui Pointer to the gui structure for rendering \param[in] type Reflection type to look up corresponding widget From 9227e5ee9bf036e0cddf59b43042c1ee3ca6e7cf Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Wed, 27 Jun 2018 13:08:09 -0700 Subject: [PATCH 16/36] Moved concat_strings macro to Framework.h, removed redundant documentation for multi-element GUI widget functions such as float1-4. All float widget functions take the same formatting parameters --- Framework/Source/Framework.h | 2 + Framework/Source/Utils/Gui.cpp | 58 ++++++++----------- Framework/Source/Utils/Gui.h | 100 ++++----------------------------- 3 files changed, 36 insertions(+), 124 deletions(-) diff --git a/Framework/Source/Framework.h b/Framework/Source/Framework.h index cc227a1ec..f48e01b5e 100644 --- a/Framework/Source/Framework.h +++ b/Framework/Source/Framework.h @@ -74,6 +74,8 @@ using namespace glm; #define safe_delete(_a) {delete _a; _a = nullptr;} #define safe_delete_array(_a) {delete[] _a; _a = nullptr;} #define align_to(_alignment, _val) (((_val + _alignment - 1) / _alignment) * _alignment) +#define concat_strings_(a, b) a##b +#define concat_strings(a, b) concat_strings_(a, b) #if defined(_MSC_VER) #define FALCOR_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE)) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index b899d7172..45b01304d 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -276,22 +276,7 @@ namespace Falcor return modified; } - bool Gui::addBool2Var(const char label[], glm::bvec2& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 2, sameLine); - } - - bool Gui::addBool3Var(const char label[], glm::bvec3& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 3, sameLine); - } - - bool Gui::addBool4Var(const char label[], glm::bvec4& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 4, sameLine); - } - - bool Gui::addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) + bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) { bool modified = false; std::string labelString(label); @@ -302,10 +287,25 @@ namespace Falcor labelString[labelString.size() - 2] = '0' + static_cast(i); modified |= addCheckBox(labelString.c_str(), pData[i], sameLine); } - + return modified; } + bool Gui::addBool2Var(const char label[], glm::bvec2& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 2, sameLine); + } + + bool Gui::addBool3Var(const char label[], glm::bvec3& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 3, sameLine); + } + + bool Gui::addBool4Var(const char label[], glm::bvec4& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 4, sameLine); + } + void Gui::addText(const char text[], bool sameLine) { if (sameLine) ImGui::SameLine(); @@ -360,29 +360,26 @@ namespace Falcor return b; } - bool Gui::addFloat2Var(const char label[], glm::vec2& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat2Var(const char label[], glm::vec2& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat2(label, glm::value_ptr(var), speed, minVal, maxVal); + bool b = ImGui::DragFloat2(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } - bool Gui::addFloat3Var(const char label[], glm::vec3& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat3Var(const char label[], glm::vec3& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat3(label, glm::value_ptr(var), speed, minVal, maxVal); + bool b = ImGui::DragFloat3(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } - bool Gui::addFloat4Var(const char label[], glm::vec4& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat4Var(const char label[], glm::vec4& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat4(label, glm::value_ptr(var), speed, maxVal, minVal); + bool b = ImGui::DragFloat4(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } @@ -419,21 +416,17 @@ namespace Falcor return b; } -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define add_matrix_function(funcName, matrixSize, baseFunc) \ - bool concatStrings(Gui::, funcName) (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ + bool concat_strings(Gui::, funcName) (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ { \ std::string labelString(label); \ labelString.append("[0]"); \ bool b = false; \ - \ for (uint32_t i = 0; i < static_cast(var.length()); ++i) \ { \ labelString[labelString.size() - 2] = '0' + static_cast(i); \ b |= baseFunc (labelString.c_str(), var[i], minVal, maxVal, sameLine); \ } \ - \ return b;\ } @@ -446,10 +439,7 @@ namespace Falcor add_matrix_function(addMatrix4x2Var, 4x2, addFloat2Var) add_matrix_function(addMatrix4x3Var, 4x3, addFloat3Var) add_matrix_function(addMatrix4x4Var, 4x4, addFloat4Var) - #undef add_matrix_function -#undef concatStrings -#undef concatStrings_ bool Gui::addRgbColor(const char label[], glm::vec3& var, bool sameLine) { diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 43edc0eff..ca3339734 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -132,36 +132,9 @@ namespace Falcor \return true if the value changed, otherwise false */ bool addFloatVar(const char label[], float& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); - - /** Adds a 2-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float2 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element ofthe vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat2Var(const char label[], glm::vec2& var, float minVal = -1, float maxVal = 1, bool sameLine = false); - - /** Adds a 3-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float3 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element of the vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat3Var(const char label[], glm::vec3& var, float minVal = -1, float maxVal = 1, bool sameLine = false); - - /** Adds a 4-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float4 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element of the vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat4Var(const char label[], glm::vec4& var, float minVal = -1, float maxVal = 1, bool sameLine = false); + bool addFloat2Var(const char label[], glm::vec2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); + bool addFloat3Var(const char label[], glm::vec3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); + bool addFloat4Var(const char label[], glm::vec4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); /** Adds a checkbox. \param[in] label The name of the checkbox. @@ -179,39 +152,16 @@ namespace Falcor */ bool addCheckBox(const char label[], int& pVar, bool sameLine = false); - /** Adds a checkbox. - \param[in] label The name of the checkbox. + /** Adds a UI widget for multiple checkboxes. + \param[in] label The name of the widget. \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ bool addBool2Var(const char lable[], glm::bvec2& var, bool sameLine = false); - - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addBool3Var(const char lable[], glm::bvec3& var, bool sameLine = false); - - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addBool4Var(const char lable[], glm::bvec4& var, bool sameLine = false); - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var Pointer to the array of bools to fill checkboxes for - \param[in] numCheckboxes number of checkbox widgets to create for same number of bools - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); - /** Adds an RGB color UI widget. \param[in] label The name of the widget. \param[in] var A reference to a vector that will be updated directly when the widget state changes. @@ -228,7 +178,7 @@ namespace Falcor */ bool addRgbaColor(const char label[], glm::vec4& var, bool sameLine = false); - /** Adds an integer UI widget. + /** Adds a UI widget for integers. \param[in] label The name of the widget. \param[in] var A reference to an integer that will be updated directly when the widget state changes. \param[in] minVal Optional. The minimum allowed value for the variable. @@ -238,35 +188,8 @@ namespace Falcor \return true if the value changed, otherwise false */ bool addIntVar(const char label[], int32_t& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, int step = 1, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to two integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt2Var(const char label[], glm::ivec2& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 3 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt3Var(const char label[], glm::ivec3& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 4 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt4Var(const char label[], glm::ivec4& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); /** Adds an matrix UI widget. @@ -277,10 +200,8 @@ namespace Falcor \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define add_matrix_function(funcName, matrixSize) \ - bool funcName (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal = -1, float maxVal = 1, bool sameLine = false) + bool funcName (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false) add_matrix_function(addMatrix2x2Var, 2x2); add_matrix_function(addMatrix2x3Var, 2x3); @@ -291,11 +212,7 @@ namespace Falcor add_matrix_function(addMatrix4x2Var, 4x2); add_matrix_function(addMatrix4x3Var, 4x3); add_matrix_function(addMatrix4x4Var, 4x4); - #undef add_matrix_function -#undef concatStrings -#undef concatStrings_ - /** Add a separator */ @@ -382,6 +299,9 @@ namespace Falcor void init(); void createVao(uint32_t vertexCount, uint32_t indexCount); + // Helper to create multiple inline text boxes + bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); + struct ComboData { uint32_t lastVal = -1; From 4e245b125b09abeac8d106e21b6d4d88bae1219d Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Wed, 27 Jun 2018 13:42:41 -0700 Subject: [PATCH 17/36] Fixed assignment in a ternary in Bitmap.cpp --- Framework/Source/Utils/Bitmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Source/Utils/Bitmap.cpp b/Framework/Source/Utils/Bitmap.cpp index 57b2132c6..e6fd6987d 100644 --- a/Framework/Source/Utils/Bitmap.cpp +++ b/Framework/Source/Utils/Bitmap.cpp @@ -326,7 +326,7 @@ namespace Falcor // Lossless formats case FileFormat::PngFile: - flags = is_set(exportFlags, ExportFlags::Uncompressed) ? flags = PNG_Z_NO_COMPRESSION : PNG_Z_BEST_COMPRESSION; + flags = is_set(exportFlags, ExportFlags::Uncompressed) ? PNG_Z_NO_COMPRESSION : PNG_Z_BEST_COMPRESSION; if (is_set(exportFlags, ExportFlags::Lossy)) { From 0a15ff38e0031cb5b93a33a889e059f033bd4ca1 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Wed, 27 Jun 2018 13:59:08 -0700 Subject: [PATCH 18/36] Fixes compilation errors for linux --- Framework/Source/API/ConstantBuffer.cpp | 7 +------ Framework/Source/Utils/Gui.cpp | 2 +- Framework/Source/Utils/Gui.h | 2 +- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 50f4cca7f..8e3b47ec7 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -88,13 +88,10 @@ namespace Falcor bool ConstantBuffer::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) { - unsigned displayIndex = 0; bool returnValue = false; -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define to_gui_widget(widgetName, baseType) \ - returnValue = pGui-> concatStrings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ + returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ offset += sizeof(baseType); switch (type) @@ -181,8 +178,6 @@ namespace Falcor break; } #undef to_gui_widget -#undef concatStrings -#undef concatStrings_ return returnValue; } diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 45b01304d..6e1abde83 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -417,7 +417,7 @@ namespace Falcor } #define add_matrix_function(funcName, matrixSize, baseFunc) \ - bool concat_strings(Gui::, funcName) (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ + bool Gui::funcName(const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ { \ std::string labelString(label); \ labelString.append("[0]"); \ diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index ca3339734..997887176 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -300,7 +300,7 @@ namespace Falcor void createVao(uint32_t vertexCount, uint32_t indexCount); // Helper to create multiple inline text boxes - bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); + bool addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); struct ComboData { From 7acb0f5335479d74f2b4d96ad5db42d6b7e322e1 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Wed, 27 Jun 2018 13:08:09 -0700 Subject: [PATCH 19/36] Moved concat_strings macro to Framework.h, removed redundant documentation for multi-element GUI widget functions such as float1-4. All float widget functions take the same formatting parameters --- Framework/Source/API/ConstantBuffer.cpp | 9 +-- Framework/Source/Framework.h | 2 + Framework/Source/Utils/Gui.cpp | 58 ++++++-------- Framework/Source/Utils/Gui.h | 100 +++--------------------- 4 files changed, 37 insertions(+), 132 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 50f4cca7f..f6ff1ea80 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -91,10 +91,8 @@ namespace Falcor unsigned displayIndex = 0; bool returnValue = false; -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define to_gui_widget(widgetName, baseType) \ - returnValue = pGui-> concatStrings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ + returnValue = pGui->concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ offset += sizeof(baseType); switch (type) @@ -181,8 +179,6 @@ namespace Falcor break; } #undef to_gui_widget -#undef concatStrings -#undef concatStrings_ return returnValue; } @@ -334,9 +330,6 @@ namespace Falcor // begin recursion on first struct renderUIInternal(pGui, pStruct, "", 0); - // dirty flag for uploading will be set by GUI - uploadToGPU(); - pGui->endGroup(); } } diff --git a/Framework/Source/Framework.h b/Framework/Source/Framework.h index cc227a1ec..f48e01b5e 100644 --- a/Framework/Source/Framework.h +++ b/Framework/Source/Framework.h @@ -74,6 +74,8 @@ using namespace glm; #define safe_delete(_a) {delete _a; _a = nullptr;} #define safe_delete_array(_a) {delete[] _a; _a = nullptr;} #define align_to(_alignment, _val) (((_val + _alignment - 1) / _alignment) * _alignment) +#define concat_strings_(a, b) a##b +#define concat_strings(a, b) concat_strings_(a, b) #if defined(_MSC_VER) #define FALCOR_DEPRECATED(MESSAGE) __declspec(deprecated(MESSAGE)) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index b899d7172..45b01304d 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -276,22 +276,7 @@ namespace Falcor return modified; } - bool Gui::addBool2Var(const char label[], glm::bvec2& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 2, sameLine); - } - - bool Gui::addBool3Var(const char label[], glm::bvec3& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 3, sameLine); - } - - bool Gui::addBool4Var(const char label[], glm::bvec4& var, bool sameLine) - { - return addNCheckboxes(label, glm::value_ptr(var), 4, sameLine); - } - - bool Gui::addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) + bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) { bool modified = false; std::string labelString(label); @@ -302,10 +287,25 @@ namespace Falcor labelString[labelString.size() - 2] = '0' + static_cast(i); modified |= addCheckBox(labelString.c_str(), pData[i], sameLine); } - + return modified; } + bool Gui::addBool2Var(const char label[], glm::bvec2& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 2, sameLine); + } + + bool Gui::addBool3Var(const char label[], glm::bvec3& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 3, sameLine); + } + + bool Gui::addBool4Var(const char label[], glm::bvec4& var, bool sameLine) + { + return addCheckboxes(label, glm::value_ptr(var), 4, sameLine); + } + void Gui::addText(const char text[], bool sameLine) { if (sameLine) ImGui::SameLine(); @@ -360,29 +360,26 @@ namespace Falcor return b; } - bool Gui::addFloat2Var(const char label[], glm::vec2& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat2Var(const char label[], glm::vec2& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat2(label, glm::value_ptr(var), speed, minVal, maxVal); + bool b = ImGui::DragFloat2(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } - bool Gui::addFloat3Var(const char label[], glm::vec3& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat3Var(const char label[], glm::vec3& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat3(label, glm::value_ptr(var), speed, minVal, maxVal); + bool b = ImGui::DragFloat3(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } - bool Gui::addFloat4Var(const char label[], glm::vec4& var, float minVal, float maxVal, bool sameLine) + bool Gui::addFloat4Var(const char label[], glm::vec4& var, float minVal, float maxVal, float step, bool sameLine, const char* displayFormat) { if (sameLine) ImGui::SameLine(); - float speed = min(1.0f, (maxVal - minVal) * 0.01f); - bool b = ImGui::DragFloat4(label, glm::value_ptr(var), speed, maxVal, minVal); + bool b = ImGui::DragFloat4(label, glm::value_ptr(var), step, minVal, maxVal, displayFormat); var = clamp(var, minVal, maxVal); return b; } @@ -419,21 +416,17 @@ namespace Falcor return b; } -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define add_matrix_function(funcName, matrixSize, baseFunc) \ - bool concatStrings(Gui::, funcName) (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ + bool concat_strings(Gui::, funcName) (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ { \ std::string labelString(label); \ labelString.append("[0]"); \ bool b = false; \ - \ for (uint32_t i = 0; i < static_cast(var.length()); ++i) \ { \ labelString[labelString.size() - 2] = '0' + static_cast(i); \ b |= baseFunc (labelString.c_str(), var[i], minVal, maxVal, sameLine); \ } \ - \ return b;\ } @@ -446,10 +439,7 @@ namespace Falcor add_matrix_function(addMatrix4x2Var, 4x2, addFloat2Var) add_matrix_function(addMatrix4x3Var, 4x3, addFloat3Var) add_matrix_function(addMatrix4x4Var, 4x4, addFloat4Var) - #undef add_matrix_function -#undef concatStrings -#undef concatStrings_ bool Gui::addRgbColor(const char label[], glm::vec3& var, bool sameLine) { diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 43edc0eff..997887176 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -132,36 +132,9 @@ namespace Falcor \return true if the value changed, otherwise false */ bool addFloatVar(const char label[], float& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); - - /** Adds a 2-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float2 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element ofthe vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat2Var(const char label[], glm::vec2& var, float minVal = -1, float maxVal = 1, bool sameLine = false); - - /** Adds a 3-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float3 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element of the vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat3Var(const char label[], glm::vec3& var, float minVal = -1, float maxVal = 1, bool sameLine = false); - - /** Adds a 4-elements floating-point vector UI element. - \param[in] label The name of the widget. - \param[in] var A reference to a float4 that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for each element of the vector. - \param[in] maxVal Optional. The maximum allowed value for each element of the vector. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addFloat4Var(const char label[], glm::vec4& var, float minVal = -1, float maxVal = 1, bool sameLine = false); + bool addFloat2Var(const char label[], glm::vec2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); + bool addFloat3Var(const char label[], glm::vec3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); + bool addFloat4Var(const char label[], glm::vec4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false, const char* displayFormat = "%.3f"); /** Adds a checkbox. \param[in] label The name of the checkbox. @@ -179,39 +152,16 @@ namespace Falcor */ bool addCheckBox(const char label[], int& pVar, bool sameLine = false); - /** Adds a checkbox. - \param[in] label The name of the checkbox. + /** Adds a UI widget for multiple checkboxes. + \param[in] label The name of the widget. \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ bool addBool2Var(const char lable[], glm::bvec2& var, bool sameLine = false); - - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addBool3Var(const char lable[], glm::bvec3& var, bool sameLine = false); - - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var A reference to the bools that will be updated directly when the checkbox state changes (0 = unchecked, 1 = checked). - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addBool4Var(const char lable[], glm::bvec4& var, bool sameLine = false); - /** Adds a checkbox. - \param[in] label The name of the checkbox. - \param[in] var Pointer to the array of bools to fill checkboxes for - \param[in] numCheckboxes number of checkbox widgets to create for same number of bools - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ - bool addNCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); - /** Adds an RGB color UI widget. \param[in] label The name of the widget. \param[in] var A reference to a vector that will be updated directly when the widget state changes. @@ -228,7 +178,7 @@ namespace Falcor */ bool addRgbaColor(const char label[], glm::vec4& var, bool sameLine = false); - /** Adds an integer UI widget. + /** Adds a UI widget for integers. \param[in] label The name of the widget. \param[in] var A reference to an integer that will be updated directly when the widget state changes. \param[in] minVal Optional. The minimum allowed value for the variable. @@ -238,35 +188,8 @@ namespace Falcor \return true if the value changed, otherwise false */ bool addIntVar(const char label[], int32_t& var, int minVal = -INT32_MAX, int maxVal = INT32_MAX, int step = 1, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to two integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt2Var(const char label[], glm::ivec2& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 3 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt3Var(const char label[], glm::ivec3& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); - - /** Adds an integer UI widget. - \param[in] label The name of the widget. - \param[in] var A reference to a vector of 4 integers that will be updated directly when the widget state changes. - \param[in] minVal Optional. The minimum allowed value for the variable. - \param[in] maxVal Optional. The maximum allowed value for the variable. - \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget - \return true if the value changed, otherwise false - */ bool addInt4Var(const char label[], glm::ivec4& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); /** Adds an matrix UI widget. @@ -277,10 +200,8 @@ namespace Falcor \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ -#define concatStrings_(a, b) a##b -#define concatStrings(a, b) concatStrings_(a, b) #define add_matrix_function(funcName, matrixSize) \ - bool funcName (const char label[], concatStrings(glm::mat, matrixSize) & var, float minVal = -1, float maxVal = 1, bool sameLine = false) + bool funcName (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false) add_matrix_function(addMatrix2x2Var, 2x2); add_matrix_function(addMatrix2x3Var, 2x3); @@ -291,11 +212,7 @@ namespace Falcor add_matrix_function(addMatrix4x2Var, 4x2); add_matrix_function(addMatrix4x3Var, 4x3); add_matrix_function(addMatrix4x4Var, 4x4); - #undef add_matrix_function -#undef concatStrings -#undef concatStrings_ - /** Add a separator */ @@ -382,6 +299,9 @@ namespace Falcor void init(); void createVao(uint32_t vertexCount, uint32_t indexCount); + // Helper to create multiple inline text boxes + bool addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine); + struct ComboData { uint32_t lastVal = -1; From 11f6426acfd90c3e17fe03bdcaab94ff5a872570 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Wed, 27 Jun 2018 13:59:08 -0700 Subject: [PATCH 20/36] Fixes compilation errors for linux --- Framework/Source/API/ConstantBuffer.cpp | 1 - Framework/Source/Utils/Gui.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index f6ff1ea80..7929a45a6 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -88,7 +88,6 @@ namespace Falcor bool ConstantBuffer::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) { - unsigned displayIndex = 0; bool returnValue = false; #define to_gui_widget(widgetName, baseType) \ diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 45b01304d..6e1abde83 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -417,7 +417,7 @@ namespace Falcor } #define add_matrix_function(funcName, matrixSize, baseFunc) \ - bool concat_strings(Gui::, funcName) (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ + bool Gui::funcName(const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ { \ std::string labelString(label); \ labelString.append("[0]"); \ From 3c93a2db4def919f81a84b212d29ef054810b33e Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Wed, 27 Jun 2018 17:18:29 -0700 Subject: [PATCH 21/36] Fixed logic in saving images to file with/without alpha --- Framework/Source/Utils/Bitmap.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Source/Utils/Bitmap.cpp b/Framework/Source/Utils/Bitmap.cpp index e6fd6987d..9ffb0223f 100644 --- a/Framework/Source/Utils/Bitmap.cpp +++ b/Framework/Source/Utils/Bitmap.cpp @@ -300,7 +300,7 @@ namespace Falcor else { FIBITMAP* pTemp = FreeImage_ConvertFromRawBits((BYTE*)pData, width, height, bytesPerPixel * width, bytesPerPixel * 8, FI_RGBA_RED_MASK, FI_RGBA_GREEN_MASK, FI_RGBA_BLUE_MASK, isTopDown); - if(is_set(exportFlags, ExportFlags::ExportAlpha) || fileFormat == Bitmap::FileFormat::JpegFile) + if(is_set(exportFlags, ExportFlags::ExportAlpha) == false || fileFormat == Bitmap::FileFormat::JpegFile) { pImage = FreeImage_ConvertTo24Bits(pTemp); FreeImage_Unload(pTemp); From e6e66953788d10f1b2432ee070a963550cfe7814 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Thu, 28 Jun 2018 16:53:42 -0700 Subject: [PATCH 22/36] Updated definition for renderUI to take user defined group label --- Framework/Source/API/ConstantBuffer.cpp | 4 ++-- Framework/Source/API/ConstantBuffer.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 8e3b47ec7..5b46b1b5c 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -318,11 +318,11 @@ namespace Falcor } } - void ConstantBuffer::renderUI(Gui* pGui) + void ConstantBuffer::renderUI(Gui* pGui, const char* uiGroup) { const ReflectionStructType* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); - if (pGui->beginGroup(std::string("ConstantBuffer: ").append(mName))) + if (!uiGroup || pGui->beginGroup(uiGroup)) { pGui->addSeparator(); diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index 2c00cc43d..da0cc6d69 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -139,7 +139,7 @@ namespace Falcor /** Renders ui for reflected data within the buffer. \param[in] pGui Pointer to the gui structure for rendering */ - void renderUI(Gui* pGui); + void renderUI(Gui* pGui, const char* uiGroup = nullptr); virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; From 6e2c34c9d1733ac9a55dea4b54e978f3799e0a05 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Thu, 28 Jun 2018 19:45:09 -0700 Subject: [PATCH 23/36] Moved renderUI internals to VariableBuffersUI class. --- Framework/Source/API/ConstantBuffer.cpp | 250 +--------------- Framework/Source/API/ConstantBuffer.h | 32 +-- Framework/Source/API/VariablesBuffer.h | 2 + Framework/Source/Falcor.vcxproj | 2 + Framework/Source/Falcor.vcxproj.filters | 6 + Framework/Source/Utils/Gui.cpp | 12 +- Framework/Source/Utils/Gui.h | 22 +- Framework/Source/Utils/VariablesBufferUI.cpp | 282 +++++++++++++++++++ Framework/Source/Utils/VariablesBufferUI.h | 76 +++++ 9 files changed, 389 insertions(+), 295 deletions(-) create mode 100644 Framework/Source/Utils/VariablesBufferUI.cpp create mode 100644 Framework/Source/Utils/VariablesBufferUI.h diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index 5b46b1b5c..da482ded0 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -35,7 +35,7 @@ #include "API/Device.h" #include "Renderer.h" -#include "Utils/Gui.h" +#include "Utils/VariablesBufferUI.h" namespace Falcor { @@ -86,253 +86,9 @@ namespace Falcor return mpCbv; } - bool ConstantBuffer::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name) - { - bool returnValue = false; - -#define to_gui_widget(widgetName, baseType) \ - returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(mData.data() + offset)); \ - offset += sizeof(baseType); - - switch (type) - { - case ReflectionBasicType::Type::Bool4: - to_gui_widget(Bool4Var, glm::bvec4); - break; - case ReflectionBasicType::Type::Bool3: - to_gui_widget(Bool3Var, glm::bvec3); - break; - case ReflectionBasicType::Type::Bool2: - to_gui_widget(Bool2Var, glm::bvec2); - break; - case ReflectionBasicType::Type::Bool: - to_gui_widget(CheckBox, bool); - break; - case ReflectionBasicType::Type::Uint4: - case ReflectionBasicType::Type::Uint64_4: - case ReflectionBasicType::Type::Int4: - case ReflectionBasicType::Type::Int64_4: - to_gui_widget(Int4Var, glm::ivec4); - break; - case ReflectionBasicType::Type::Uint3: - case ReflectionBasicType::Type::Uint64_3: - case ReflectionBasicType::Type::Int3: - case ReflectionBasicType::Type::Int64_3: - to_gui_widget(Int3Var, glm::ivec3); - break; - case ReflectionBasicType::Type::Uint2: - case ReflectionBasicType::Type::Uint64_2: - case ReflectionBasicType::Type::Int2: - case ReflectionBasicType::Type::Int64_2: - to_gui_widget(Int2Var, glm::ivec2); - break; - case ReflectionBasicType::Type::Uint: - case ReflectionBasicType::Type::Uint64: - case ReflectionBasicType::Type::Int: - case ReflectionBasicType::Type::Int64: - to_gui_widget(IntVar, int); - break; - case ReflectionBasicType::Type::Float: - to_gui_widget(FloatVar, float); - break; - case ReflectionBasicType::Type::Float2: - to_gui_widget(Float2Var, glm::vec2); - break; - case ReflectionBasicType::Type::Float3: - to_gui_widget(Float3Var, glm::vec3); - break; - case ReflectionBasicType::Type::Float4: - to_gui_widget(Float4Var, glm::vec4); - break; - case ReflectionBasicType::Type::Float2x2: - to_gui_widget(Matrix2x2Var, glm::mat2x2); - break; - case ReflectionBasicType::Type::Float2x3: - to_gui_widget(Matrix2x3Var, glm::mat2x3); - break; - case ReflectionBasicType::Type::Float2x4: - to_gui_widget(Matrix2x4Var, glm::mat2x4); - break; - case ReflectionBasicType::Type::Float3x2: - to_gui_widget(Matrix3x2Var, glm::mat3x2); - break; - case ReflectionBasicType::Type::Float3x3: - to_gui_widget(Matrix3x3Var, glm::mat3x3); - break; - case ReflectionBasicType::Type::Float3x4: - to_gui_widget(Matrix3x4Var, glm::mat3x4); - break; - case ReflectionBasicType::Type::Float4x2: - to_gui_widget(Matrix4x2Var, glm::mat4x2); - break; - case ReflectionBasicType::Type::Float4x3: - to_gui_widget(Matrix4x3Var, glm::mat4x3); - break; - case ReflectionBasicType::Type::Float4x4: - to_gui_widget(Matrix4x4Var, glm::mat4x4); - break; - case ReflectionBasicType::Type::Unknown: - break; - default: - should_not_get_here(); - break; - } -#undef to_gui_widget - - return returnValue; - } - - void ConstantBuffer::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType) - { - // Display reflection data and gather offset - pGui->addText("Name: ", false); - pGui->addText(memberName.c_str(), true); - pGui->addText("Offset: ", false); - pGui->addText(std::to_string(memberOffset).c_str(), true); - pGui->addText(" Size: ", true); - pGui->addText(std::to_string(memberSize).c_str(), true); - pGui->addText(" Type: ", true); - pGui->addText(memberTypeString.c_str(), true); - - // Display data from the stage memory - mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName); - - pGui->addSeparator(); - } - - void ConstantBuffer::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset) - { - for (auto memberIt = pStruct->begin(); memberIt != pStruct->end(); ++memberIt) - { - size_t numMembers = 1; - size_t memberSize = 0; - ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; - std::string memberName = (*memberIt)->getName(); - const ReflectionBasicType* pBasicType = (*memberIt)->getType()->asBasicType(); - const ReflectionArrayType* pArrayType = nullptr; - bool baseTypeIsStruct = false; - bool arrayGroupStatus = false; - size_t currentOffset = startOffset + (*memberIt)->getOffset(); - - // First test is not basic type - if (!pBasicType) - { - // recurse through struct if possible - const ReflectionStructType* pStructType = (*memberIt)->getType()->asStructType(); - if (pStructType) - { - // Iterate through the internal struct - if (pGui->beginGroup(memberName)) - { - memberName.push_back('.'); - renderUIInternal(pGui, pStructType, memberName, currentOffset); - memberName.pop_back(); - - pGui->endGroup(); - } - pGui->addSeparator(); - - // skip to next member - continue; - } - - // if array type gather info for iterating through elements - pArrayType = (*memberIt)->getType()->asArrayType(); - - if (pArrayType) - { - pGui->addSeparator(); - - // only iterate through array if it is displaying - arrayGroupStatus = pGui->beginGroup(memberName + "[]"); - if (!arrayGroupStatus) - { - pGui->addSeparator(); - continue; - } - - const ReflectionBasicType* elementBasicType = pArrayType->getType()->asBasicType(); - numMembers = pArrayType->getArraySize(); - memberSize = pArrayType->getArrayStride(); - - if (elementBasicType) - { - memberType = elementBasicType->getType(); - } - else - { - // for special case of array of structures - baseTypeIsStruct = true; - } - } - else if (!pStructType) - { - // Other types could be presented here - return; - } - } - else - { - // information if only basic type - memberType = pBasicType->getType(); - memberSize = pBasicType->getSize(); - } - - - // Display member of the array - int32_t memberIndex = 0; - std::string displayName = memberName; - - if (numMembers > 1) - { - // display information for specific index of array - memberIndex = mGuiArrayIndices[displayName]; - pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), memberIndex, 0, static_cast(numMembers) - 1); - currentOffset += (memberSize * memberIndex); - displayName.append("[").append(std::to_string(memberIndex)).append("]"); - } - - if (baseTypeIsStruct) - { - // For arrays of structs, display dropdown for struct before recursing through struct members - if (pGui->beginGroup(displayName)) - { - displayName.push_back('.'); - renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset); - pGui->endGroup(); - } - } - else - { - // for basic types - renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType); - } - - currentOffset += memberSize; - - - if (arrayGroupStatus) - { - pGui->endGroup(); - } - } - } - void ConstantBuffer::renderUI(Gui* pGui, const char* uiGroup) { - const ReflectionStructType* pStruct = mpReflector->asResourceType()->getStructType()->asStructType(); - - if (!uiGroup || pGui->beginGroup(uiGroup)) - { - pGui->addSeparator(); - - // begin recursion on first struct - renderUIInternal(pGui, pStruct, "", 0); - - // dirty flag for uploading will be set by GUI - uploadToGPU(); - - pGui->endGroup(); - } + VariablesBufferUI variablesBufferUI(*this); + variablesBufferUI.renderUI(pGui, uiGroup); } } \ No newline at end of file diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index da0cc6d69..f60ce9be0 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -36,7 +36,6 @@ namespace Falcor { class Sampler; // Forward declares for gui draw func - class SampleCallbacks; class Gui; /** Abstracts a Constant/Uniform buffer. @@ -137,7 +136,8 @@ namespace Falcor } /** Renders ui for reflected data within the buffer. - \param[in] pGui Pointer to the gui structure for rendering + \param[in] pGui Pointer to the GUI structure for rendering + \param[in] uiGroup optional label for GUI */ void renderUI(Gui* pGui, const char* uiGroup = nullptr); @@ -148,33 +148,5 @@ namespace Falcor private: ConstantBuffer(const std::string& name, const ReflectionResourceType::SharedConstPtr& pReflectionType, size_t size); mutable ConstantBufferView::SharedPtr mpCbv; - - std::unordered_map mGuiArrayIndices; - - /** Call the corresponding gui function using the reflected data - \param[in] pGui Pointer to the gui structure for rendering - \param[in] type Reflection type to look up corresponding widget - \param[in] offset offset into the data array of the constant buffer - \param[in] name String name for widget to display - \return true if data was changed from the widget. internal used to call upload to gpu - */ - bool renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); - - /** Recursive function for traversing reflection data and display ui - \param[in] pGui Pointer to the gui structure for rendering - \param[in] pStruct Pointer to structure to iterate and display for the gui - \param[in] currentStructName Current struct name to append for full reflection name - \param[in] startOffset Starting offset in memory for nested structures - */ - void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset); - - /** Render gui widget for reflected data - \param[in] pGui Pointer to the gui structure for rendering - \param[in] memberName string containing the name of the data member to render - \param[in] memberOffset offset into the data array - \param[in] memberSize size of the data in the member - \param[in] memberType reflection type enum for the basic type - */ - void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType); }; } diff --git a/Framework/Source/API/VariablesBuffer.h b/Framework/Source/API/VariablesBuffer.h index 33ae0002f..06a8201cd 100644 --- a/Framework/Source/API/VariablesBuffer.h +++ b/Framework/Source/API/VariablesBuffer.h @@ -80,6 +80,8 @@ namespace Falcor size_t getElementSize() const { return mElementSize; } + friend class VariablesBufferUI; + protected: template void setVariable(const std::string& name, size_t elementIndex, const T& value); diff --git a/Framework/Source/Falcor.vcxproj b/Framework/Source/Falcor.vcxproj index f5c584ac1..e956e6197 100644 --- a/Framework/Source/Falcor.vcxproj +++ b/Framework/Source/Falcor.vcxproj @@ -550,6 +550,7 @@ + @@ -1122,6 +1123,7 @@ + diff --git a/Framework/Source/Falcor.vcxproj.filters b/Framework/Source/Falcor.vcxproj.filters index 9f2b8ec60..b353c6a19 100644 --- a/Framework/Source/Falcor.vcxproj.filters +++ b/Framework/Source/Falcor.vcxproj.filters @@ -535,6 +535,9 @@ Effects\FXAA + + Utils + @@ -1693,6 +1696,9 @@ Effects\FXAA + + Utils + diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 6e1abde83..1fd468810 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -279,15 +279,17 @@ namespace Falcor bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) { bool modified = false; - std::string labelString(label); - labelString.append("[0]"); + std::string labelString(std::string("##") + label); + labelString.push_back('0'); - for (uint32_t i = 0; i < numCheckboxes; ++i) + for (uint32_t i = 0; i < numCheckboxes - 1; ++i) { - labelString[labelString.size() - 2] = '0' + static_cast(i); - modified |= addCheckBox(labelString.c_str(), pData[i], sameLine); + labelString[labelString.size() - 1] = '0' + static_cast(i); + modified |= addCheckBox(labelString.c_str(), pData[i], (!i) ? sameLine : true); } + addCheckBox(label, pData[numCheckboxes - 1], (numCheckboxes == 1) ? sameLine : true ); + return modified; } diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 997887176..606874511 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -200,19 +200,15 @@ namespace Falcor \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ -#define add_matrix_function(funcName, matrixSize) \ - bool funcName (const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false) - - add_matrix_function(addMatrix2x2Var, 2x2); - add_matrix_function(addMatrix2x3Var, 2x3); - add_matrix_function(addMatrix2x4Var, 2x4); - add_matrix_function(addMatrix3x2Var, 3x2); - add_matrix_function(addMatrix3x3Var, 3x3); - add_matrix_function(addMatrix3x4Var, 3x4); - add_matrix_function(addMatrix4x2Var, 4x2); - add_matrix_function(addMatrix4x3Var, 4x3); - add_matrix_function(addMatrix4x4Var, 4x4); -#undef add_matrix_function + bool addMatrix2x2Var(const char label[], glm::mat2x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix2x3Var(const char label[], glm::mat2x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix2x4Var(const char label[], glm::mat2x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix3x2Var(const char label[], glm::mat3x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix3x3Var(const char label[], glm::mat3x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix3x4Var(const char label[], glm::mat3x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix4x2Var(const char label[], glm::mat4x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix4x3Var(const char label[], glm::mat4x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + bool addMatrix4x4Var(const char label[], glm::mat4x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); /** Add a separator */ diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp new file mode 100644 index 000000000..5f63e950a --- /dev/null +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -0,0 +1,282 @@ +/*************************************************************************** +# Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************/ + +#include "VariablesBufferUI.h" +#include "Utils/Gui.h" + +namespace Falcor +{ + std::unordered_map VariablesBufferUI::mGuiArrayIndices; + + bool VariablesBufferUI::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name)//, std::vector& data) + { + bool returnValue = false; + +#define to_gui_widget(widgetName, baseType) \ + returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(mVariabelsBufferRef.mData.data() + offset)); \ + offset += sizeof(baseType); + + switch (type) + { + case ReflectionBasicType::Type::Bool4: + to_gui_widget(Bool4Var, glm::bvec4); + break; + case ReflectionBasicType::Type::Bool3: + to_gui_widget(Bool3Var, glm::bvec3); + break; + case ReflectionBasicType::Type::Bool2: + to_gui_widget(Bool2Var, glm::bvec2); + break; + case ReflectionBasicType::Type::Bool: + to_gui_widget(CheckBox, bool); + break; + case ReflectionBasicType::Type::Uint4: + case ReflectionBasicType::Type::Uint64_4: + case ReflectionBasicType::Type::Int4: + case ReflectionBasicType::Type::Int64_4: + to_gui_widget(Int4Var, glm::ivec4); + break; + case ReflectionBasicType::Type::Uint3: + case ReflectionBasicType::Type::Uint64_3: + case ReflectionBasicType::Type::Int3: + case ReflectionBasicType::Type::Int64_3: + to_gui_widget(Int3Var, glm::ivec3); + break; + case ReflectionBasicType::Type::Uint2: + case ReflectionBasicType::Type::Uint64_2: + case ReflectionBasicType::Type::Int2: + case ReflectionBasicType::Type::Int64_2: + to_gui_widget(Int2Var, glm::ivec2); + break; + case ReflectionBasicType::Type::Uint: + case ReflectionBasicType::Type::Uint64: + case ReflectionBasicType::Type::Int: + case ReflectionBasicType::Type::Int64: + to_gui_widget(IntVar, int); + break; + case ReflectionBasicType::Type::Float: + to_gui_widget(FloatVar, float); + break; + case ReflectionBasicType::Type::Float2: + to_gui_widget(Float2Var, glm::vec2); + break; + case ReflectionBasicType::Type::Float3: + to_gui_widget(Float3Var, glm::vec3); + break; + case ReflectionBasicType::Type::Float4: + to_gui_widget(Float4Var, glm::vec4); + break; + case ReflectionBasicType::Type::Float2x2: + to_gui_widget(Matrix2x2Var, glm::mat2x2); + break; + case ReflectionBasicType::Type::Float2x3: + to_gui_widget(Matrix2x3Var, glm::mat2x3); + break; + case ReflectionBasicType::Type::Float2x4: + to_gui_widget(Matrix2x4Var, glm::mat2x4); + break; + case ReflectionBasicType::Type::Float3x2: + to_gui_widget(Matrix3x2Var, glm::mat3x2); + break; + case ReflectionBasicType::Type::Float3x3: + to_gui_widget(Matrix3x3Var, glm::mat3x3); + break; + case ReflectionBasicType::Type::Float3x4: + to_gui_widget(Matrix3x4Var, glm::mat3x4); + break; + case ReflectionBasicType::Type::Float4x2: + to_gui_widget(Matrix4x2Var, glm::mat4x2); + break; + case ReflectionBasicType::Type::Float4x3: + to_gui_widget(Matrix4x3Var, glm::mat4x3); + break; + case ReflectionBasicType::Type::Float4x4: + to_gui_widget(Matrix4x4Var, glm::mat4x4); + break; + case ReflectionBasicType::Type::Unknown: + break; + default: + should_not_get_here(); + break; + } +#undef to_gui_widget + + return returnValue; + } + + void VariablesBufferUI::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType) + { + // Display reflection data and gather offset + pGui->addText("Name: ", false); + pGui->addText(memberName.c_str(), true); + pGui->addText("Offset: ", false); + pGui->addText(std::to_string(memberOffset).c_str(), true); + pGui->addText(" Size: ", true); + pGui->addText(std::to_string(memberSize).c_str(), true); + pGui->addText(" Type: ", true); + pGui->addText(memberTypeString.c_str(), true); + + // Display data from the stage memory + mVariabelsBufferRef.mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName); + } + + void VariablesBufferUI::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, bool& dirtyFlag) + { + for (auto memberIt : *pStruct) + { + size_t numMembers = 1; + size_t memberSize = 0; + ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; + std::string memberName = (memberIt)->getName(); + const ReflectionBasicType* pBasicType = (memberIt)->getType()->asBasicType(); + const ReflectionArrayType* pArrayType = nullptr; + bool baseTypeIsStruct = false; + bool arrayGroupStatus = false; + size_t currentOffset = startOffset + (memberIt)->getOffset(); + + // First test is not basic type + if (!pBasicType) + { + // recurse through struct if possible + const ReflectionStructType* pStructType = (memberIt)->getType()->asStructType(); + if (pStructType) + { + // Iterate through the internal struct + if (pGui->beginGroup(memberName)) + { + memberName.push_back('.'); + renderUIInternal(pGui, pStructType, memberName, currentOffset, dirtyFlag); + memberName.pop_back(); + + pGui->endGroup(); + } + pGui->addSeparator(); + + // skip to next member + continue; + } + + // if array type gather info for iterating through elements + pArrayType = (memberIt)->getType()->asArrayType(); + + if (pArrayType) + { + pGui->addSeparator(); + + // only iterate through array if it is displaying + arrayGroupStatus = pGui->beginGroup(memberName + "[]"); + if (!arrayGroupStatus) + { + pGui->addSeparator(); + continue; + } + + const ReflectionBasicType* elementBasicType = pArrayType->getType()->asBasicType(); + numMembers = pArrayType->getArraySize(); + memberSize = pArrayType->getArrayStride(); + + if (elementBasicType) + { + memberType = elementBasicType->getType(); + } + else + { + // for special case of array of structures + baseTypeIsStruct = true; + } + } + else if (!pStructType) + { + // Other types could be presented here + return; + } + } + else + { + // information if only basic type + memberType = pBasicType->getType(); + memberSize = pBasicType->getSize(); + } + + + // Display member of the array + std::string displayName = memberName; + + if (numMembers > 1) + { + // display information for specific index of array + int32_t& memberIndex = mGuiArrayIndices[displayName]; + pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), memberIndex, 0, static_cast(numMembers) - 1); + currentOffset += (memberSize * memberIndex); + displayName.append("[").append(std::to_string(memberIndex)).append("]"); + } + + if (baseTypeIsStruct) + { + // For arrays of structs, display dropdown for struct before recursing through struct members + if (pGui->beginGroup(displayName)) + { + displayName.push_back('.'); + renderUIInternal(pGui, pArrayType->getType()->asStructType(), displayName, currentOffset, dirtyFlag); + pGui->endGroup(); + } + } + else + { + // for basic types + renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType); + } + + currentOffset += memberSize; + + + if (arrayGroupStatus) + { + pGui->endGroup(); + } + } + } + + void VariablesBufferUI::renderUI(Gui* pGui, const char* uiGroup) + { + const ReflectionStructType* pStruct = mVariabelsBufferRef.mpReflector->asResourceType()->getStructType()->asStructType(); + + if (!uiGroup || pGui->beginGroup(uiGroup)) + { + pGui->addSeparator(); + + // begin recursion on first struct + renderUIInternal(pGui, pStruct, "", 0, mVariabelsBufferRef.mDirty); + + // dirty flag for uploading will be set by GUI + mVariabelsBufferRef.uploadToGPU(); + + pGui->endGroup(); + } + } +} diff --git a/Framework/Source/Utils/VariablesBufferUI.h b/Framework/Source/Utils/VariablesBufferUI.h new file mode 100644 index 000000000..37b0fdfff --- /dev/null +++ b/Framework/Source/Utils/VariablesBufferUI.h @@ -0,0 +1,76 @@ +/*************************************************************************** +# Copyright (c) 2015, NVIDIA CORPORATION. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of NVIDIA CORPORATION nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +# OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +***************************************************************************/ + +#pragma once +#include "Graphics/Program/ProgramReflection.h" +#include "API/VariablesBuffer.h" + +namespace Falcor +{ + // Forward declares for gui draw func + class Gui; + + class VariablesBufferUI + { + public: + VariablesBufferUI(VariablesBuffer& variablesBufferRef) : mVariabelsBufferRef(variablesBufferRef) {} + + void renderUI(Gui* pGui, const char* uiGroup); + + private: + + VariablesBuffer& mVariabelsBufferRef; + static std::unordered_map mGuiArrayIndices; + + /** Call the corresponding gui function using the reflected data + \param[in] pGui Pointer to the gui structure for rendering + \param[in] type Reflection type to look up corresponding widget + \param[in] offset offset into the data array of the constant buffer + \param[in] name String name for widget to display + \return true if data was changed from the widget. internal used to call upload to gpu + */ + bool renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); + + /** Recursive function for traversing reflection data and display ui + \param[in] pGui Pointer to the gui structure for rendering + \param[in] pStruct Pointer to structure to iterate and display for the gui + \param[in] currentStructName Current struct name to append for full reflection name + \param[in] startOffset Starting offset in memory for nested structures + */ + void renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, bool& dirtyFlag); + + /** Render gui widget for reflected data + \param[in] pGui Pointer to the gui structure for rendering + \param[in] memberName string containing the name of the data member to render + \param[in] memberOffset offset into the data array + \param[in] memberSize size of the data in the member + \param[in] memberType reflection type enum for the basic type + */ + void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType); + }; +} From 2600f7d23d2865a6c0505287b89b1e7e871e8123 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 29 Jun 2018 16:23:36 -0700 Subject: [PATCH 24/36] Improved readibility and formatting for variablesbuffer ui --- Framework/Source/Utils/Gui.cpp | 35 ++++++++- Framework/Source/Utils/VariablesBufferUI.cpp | 83 ++++++++++---------- Framework/Source/Utils/VariablesBufferUI.h | 2 +- 3 files changed, 75 insertions(+), 45 deletions(-) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 1fd468810..8ea21d982 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -32,6 +32,7 @@ #include "Utils/UserInput.h" #include "API/RenderContext.h" #include "Externals/dear_imgui/imgui.h" +#include "Externals/dear_imgui/imgui_internal.h" #include "Utils/Math/FalcorMath.h" #include "glm/gtc/type_ptr.hpp" #include "Utils/StringUtils.h" @@ -288,6 +289,9 @@ namespace Falcor modified |= addCheckBox(labelString.c_str(), pData[i], (!i) ? sameLine : true); } + ImVec2 newCursorPosition = ImGui::GetCursorScreenPos(); + newCursorPosition.x += ImGui::GetContentRegionAvail().x; + ImGui::SetCursorScreenPos(newCursorPosition); addCheckBox(label, pData[numCheckboxes - 1], (numCheckboxes == 1) ? sameLine : true ); return modified; @@ -422,12 +426,37 @@ namespace Falcor bool Gui::funcName(const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ { \ std::string labelString(label); \ - labelString.append("[0]"); \ + std::string hiddenLabelString; \ + hiddenLabelString = "##" + labelString; \ + hiddenLabelString.append("[0]"); \ + \ + ImVec2 topLeft = ImGui::GetCursorScreenPos(); \ + ImVec2 bottomRight; \ + \ bool b = false; \ + \ for (uint32_t i = 0; i < static_cast(var.length()); ++i) \ { \ - labelString[labelString.size() - 2] = '0' + static_cast(i); \ - b |= baseFunc (labelString.c_str(), var[i], minVal, maxVal, sameLine); \ + hiddenLabelString[hiddenLabelString.size() - 2] = '0' + static_cast(i);\ + if (i != var.length() - 1) \ + { \ + b |= baseFunc (hiddenLabelString.c_str(), var[i], minVal, maxVal, sameLine);\ + } \ + else \ + { \ + b |= baseFunc(labelString.c_str(), var[i], minVal, maxVal, sameLine); \ + } \ + if(i == 1) \ + { \ + bottomRight = ImGui::GetCurrentWindow()->DC.CursorPosPrevLine; \ + bottomRight.y = topLeft.y + (bottomRight.y - topLeft.y) * (var.length()); \ + bottomRight.x -= ImGui::GetStyle().ItemInnerSpacing.x - 1; \ + bottomRight.y -= ImGui::GetStyle().ItemInnerSpacing.y - 1; \ + topLeft.x -= 1; topLeft.y -= 1; \ + auto colorVec4 =ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarGrab); colorVec4.w *= 0.25f; \ + ImU32 color = ImGui::ColorConvertFloat4ToU32(colorVec4); \ + ImGui::GetCurrentWindow()->DrawList->AddRect(topLeft, bottomRight, color); \ + } \ } \ return b;\ } diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp index 5f63e950a..71d921c40 100644 --- a/Framework/Source/Utils/VariablesBufferUI.cpp +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -129,73 +129,65 @@ namespace Falcor return returnValue; } - void VariablesBufferUI::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType) + void VariablesBufferUI::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, size_t arraySize) { - // Display reflection data and gather offset - pGui->addText("Name: ", false); - pGui->addText(memberName.c_str(), true); - pGui->addText("Offset: ", false); - pGui->addText(std::to_string(memberOffset).c_str(), true); - pGui->addText(" Size: ", true); - pGui->addText(std::to_string(memberSize).c_str(), true); - pGui->addText(" Type: ", true); - pGui->addText(memberTypeString.c_str(), true); - // Display data from the stage memory mVariabelsBufferRef.mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName); + + // Display name and then reflection data as tooltip + std::string toolTipString = "Offset: " + std::to_string(memberOffset); + toolTipString.append("\nSize: " + std::to_string(memberSize)); + if (arraySize > 1) + { + toolTipString.append("\nArray Size: " + std::to_string(arraySize)); + } + toolTipString.append("\nType: " + memberTypeString); + + pGui->addTooltip(toolTipString.c_str(), true); } void VariablesBufferUI::renderUIInternal(Gui* pGui, const ReflectionStructType* pStruct, const std::string& currentStructName, size_t startOffset, bool& dirtyFlag) { - for (auto memberIt : *pStruct) + for (auto pMember : *pStruct) { size_t numMembers = 1; size_t memberSize = 0; ReflectionBasicType::Type memberType = ReflectionBasicType::Type::Unknown; - std::string memberName = (memberIt)->getName(); - const ReflectionBasicType* pBasicType = (memberIt)->getType()->asBasicType(); + std::string memberName = (pMember)->getName(); + const ReflectionBasicType* pBasicType = (pMember)->getType()->asBasicType(); const ReflectionArrayType* pArrayType = nullptr; bool baseTypeIsStruct = false; - bool arrayGroupStatus = false; - size_t currentOffset = startOffset + (memberIt)->getOffset(); + size_t currentOffset = startOffset + (pMember)->getOffset(); // First test is not basic type if (!pBasicType) { // recurse through struct if possible - const ReflectionStructType* pStructType = (memberIt)->getType()->asStructType(); + const ReflectionStructType* pStructType = (pMember)->getType()->asStructType(); if (pStructType) { // Iterate through the internal struct if (pGui->beginGroup(memberName)) { + pGui->addSeparator(); + memberName.push_back('.'); renderUIInternal(pGui, pStructType, memberName, currentOffset, dirtyFlag); memberName.pop_back(); pGui->endGroup(); + pGui->addSeparator(); } - pGui->addSeparator(); - + // skip to next member continue; } // if array type gather info for iterating through elements - pArrayType = (memberIt)->getType()->asArrayType(); + pArrayType = (pMember)->getType()->asArrayType(); if (pArrayType) { - pGui->addSeparator(); - - // only iterate through array if it is displaying - arrayGroupStatus = pGui->beginGroup(memberName + "[]"); - if (!arrayGroupStatus) - { - pGui->addSeparator(); - continue; - } - const ReflectionBasicType* elementBasicType = pArrayType->getType()->asBasicType(); numMembers = pArrayType->getArraySize(); memberSize = pArrayType->getArrayStride(); @@ -226,16 +218,19 @@ namespace Falcor // Display member of the array std::string displayName = memberName; + int32_t& memberIndex = mGuiArrayIndices[displayName]; + std::string indexLabelString; if (numMembers > 1) { // display information for specific index of array - int32_t& memberIndex = mGuiArrayIndices[displayName]; - pGui->addIntVar((std::string("Index (Size : ") + std::to_string(numMembers) + ") ").c_str(), memberIndex, 0, static_cast(numMembers) - 1); + indexLabelString = (std::string("Index (Size : ") + std::to_string(numMembers) + ") "); + currentOffset += (memberSize * memberIndex); - displayName.append("[").append(std::to_string(memberIndex)).append("]"); + displayName.append("[0:").append(std::to_string(numMembers)).append("]"); } + if (baseTypeIsStruct) { // For arrays of structs, display dropdown for struct before recursing through struct members @@ -249,16 +244,24 @@ namespace Falcor else { // for basic types - renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType); + renderUIMemberInternal(pGui, displayName, currentOffset, memberSize, to_string(memberType), memberType, numMembers); } - currentOffset += memberSize; - - - if (arrayGroupStatus) + if (numMembers > 1) { - pGui->endGroup(); + if (pGui->addButton(("-##" + indexLabelString + displayName).c_str(), true)) + { + memberIndex--; + } + if (pGui->addButton(("+##" + indexLabelString + displayName).c_str(), true)) + { + memberIndex++; + } + + memberIndex = clamp(memberIndex, 0, static_cast(numMembers)); } + + currentOffset += memberSize; } } @@ -268,8 +271,6 @@ namespace Falcor if (!uiGroup || pGui->beginGroup(uiGroup)) { - pGui->addSeparator(); - // begin recursion on first struct renderUIInternal(pGui, pStruct, "", 0, mVariabelsBufferRef.mDirty); diff --git a/Framework/Source/Utils/VariablesBufferUI.h b/Framework/Source/Utils/VariablesBufferUI.h index 37b0fdfff..665bec12b 100644 --- a/Framework/Source/Utils/VariablesBufferUI.h +++ b/Framework/Source/Utils/VariablesBufferUI.h @@ -71,6 +71,6 @@ namespace Falcor \param[in] memberSize size of the data in the member \param[in] memberType reflection type enum for the basic type */ - void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType); + void renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, size_t arraySize = 0); }; } From b65ff989edb9512d844adeabcb197321a36e24e6 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 29 Jun 2018 16:24:10 -0700 Subject: [PATCH 25/36] index on constant-buffer-ui: 2600f7d Improved readibility and formatting for variablesbuffer ui --- Samples/ForwardRenderer/Data/ForwardRenderer.slang | 10 ++++++++++ Samples/ForwardRenderer/ForwardRendererControls.cpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/Samples/ForwardRenderer/Data/ForwardRenderer.slang b/Samples/ForwardRenderer/Data/ForwardRenderer.slang index 34709be4c..c67bbfa4e 100644 --- a/Samples/ForwardRenderer/Data/ForwardRenderer.slang +++ b/Samples/ForwardRenderer/Data/ForwardRenderer.slang @@ -38,6 +38,16 @@ layout(binding = 0) cbuffer PerFrameCB : register(b0) float4x4 camVpAtLastCsmUpdate; float2 gRenderTargetDim; float gOpacityScale; + float hereIsATest[128]; + bool testBool; + bool2 testBool2; + bool3 testBool3; + bool4 testBool4[128]; +}; + +layout(binding = 8) cbuffer Tests : register(b0) +{ + float4x4 testMatrix; }; layout(set = 1, binding = 1) SamplerState gSampler; diff --git a/Samples/ForwardRenderer/ForwardRendererControls.cpp b/Samples/ForwardRenderer/ForwardRendererControls.cpp index 392be2f99..13b1c1f68 100644 --- a/Samples/ForwardRenderer/ForwardRendererControls.cpp +++ b/Samples/ForwardRenderer/ForwardRendererControls.cpp @@ -350,5 +350,8 @@ void ForwardRenderer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) { applyLightingProgramControl(ControlID::EnableHashedAlpha); } + + mLightingPass.pVars->getConstantBuffer("PerFrameCB")->renderUI(pGui, "Constant Buffer: PerFrameCB"); + mLightingPass.pVars->getConstantBuffer("Tests")->renderUI(pGui, "Constant Buffer: Tests"); } } From ba7dd1a44b9944976d4e4d36f4e374b745f77380 Mon Sep 17 00:00:00 2001 From: nbenty Date: Fri, 29 Jun 2018 17:44:28 -0700 Subject: [PATCH 26/36] Calculate the correct row-pitch when copy texture subresource (needs to be aligned to 256) Fixed issue #86 --- Framework/Source/API/D3D12/D3D12CopyContext.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/Framework/Source/API/D3D12/D3D12CopyContext.cpp b/Framework/Source/API/D3D12/D3D12CopyContext.cpp index 7cf35d251..4afeaee58 100644 --- a/Framework/Source/API/D3D12/D3D12CopyContext.cpp +++ b/Framework/Source/API/D3D12/D3D12CopyContext.cpp @@ -89,6 +89,9 @@ namespace Falcor std::vector rowSize(subresourceCount); uint64_t bufferSize; + ID3D12Device* pDevice = gpDevice->getApiHandle(); + pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &bufferSize); + if (copyRegion) { footprint[0].Offset = 0; @@ -97,16 +100,9 @@ namespace Falcor footprint[0].Footprint.Width = (size.x == -1) ? pTexture->getWidth(mipLevel) - offset.x : size.x; footprint[0].Footprint.Height = (size.y == -1) ? pTexture->getHeight(mipLevel) - offset.y : size.y; footprint[0].Footprint.Depth = (size.z == -1) ? pTexture->getDepth(mipLevel) - offset.z : size.z; - footprint[0].Footprint.RowPitch = footprint[0].Footprint.Width * getFormatBytesPerBlock(pTexture->getFormat()); rowCount[0] = footprint[0].Footprint.Height; - rowSize[0] = footprint[0].Footprint.RowPitch; bufferSize = rowSize[0] * rowCount[0] * footprint[0].Footprint.Depth; } - else - { - ID3D12Device* pDevice = gpDevice->getApiHandle(); - pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &bufferSize); - } // Allocate a buffer on the upload heap Buffer::SharedPtr pBuffer = Buffer::create(bufferSize, Buffer::BindFlags::None, Buffer::CpuAccess::Write, nullptr); From a73c4a3b5fc03eba3256861d099c01abf1750c04 Mon Sep 17 00:00:00 2001 From: nbenty Date: Fri, 29 Jun 2018 17:47:57 -0700 Subject: [PATCH 27/36] Optimized the code a bit --- Framework/Source/API/D3D12/D3D12CopyContext.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Framework/Source/API/D3D12/D3D12CopyContext.cpp b/Framework/Source/API/D3D12/D3D12CopyContext.cpp index 4afeaee58..3802b639e 100644 --- a/Framework/Source/API/D3D12/D3D12CopyContext.cpp +++ b/Framework/Source/API/D3D12/D3D12CopyContext.cpp @@ -89,9 +89,6 @@ namespace Falcor std::vector rowSize(subresourceCount); uint64_t bufferSize; - ID3D12Device* pDevice = gpDevice->getApiHandle(); - pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &bufferSize); - if (copyRegion) { footprint[0].Offset = 0; @@ -100,9 +97,16 @@ namespace Falcor footprint[0].Footprint.Width = (size.x == -1) ? pTexture->getWidth(mipLevel) - offset.x : size.x; footprint[0].Footprint.Height = (size.y == -1) ? pTexture->getHeight(mipLevel) - offset.y : size.y; footprint[0].Footprint.Depth = (size.z == -1) ? pTexture->getDepth(mipLevel) - offset.z : size.z; + footprint[0].Footprint.RowPitch = align_to(D3D12_TEXTURE_DATA_PITCH_ALIGNMENT, footprint[0].Footprint.Width * getFormatBytesPerBlock(pTexture->getFormat())); rowCount[0] = footprint[0].Footprint.Height; + rowSize[0] = footprint[0].Footprint.RowPitch; bufferSize = rowSize[0] * rowCount[0] * footprint[0].Footprint.Depth; } + else + { + ID3D12Device* pDevice = gpDevice->getApiHandle(); + pDevice->GetCopyableFootprints(&texDesc, firstSubresource, subresourceCount, 0, footprint.data(), rowCount.data(), rowSize.data(), &bufferSize); + } // Allocate a buffer on the upload heap Buffer::SharedPtr pBuffer = Buffer::create(bufferSize, Buffer::BindFlags::None, Buffer::CpuAccess::Write, nullptr); From a79c43dda88e5f3b8d3cc621283f61c64474bc92 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Fri, 29 Jun 2018 19:38:26 -0700 Subject: [PATCH 28/36] Improves readability and formating of gui. Fixes issue with editing bvecs in variable buffer ui. --- Samples/ForwardRenderer/Data/ForwardRenderer.slang | 10 ---------- Samples/ForwardRenderer/ForwardRendererControls.cpp | 3 --- 2 files changed, 13 deletions(-) diff --git a/Samples/ForwardRenderer/Data/ForwardRenderer.slang b/Samples/ForwardRenderer/Data/ForwardRenderer.slang index c67bbfa4e..34709be4c 100644 --- a/Samples/ForwardRenderer/Data/ForwardRenderer.slang +++ b/Samples/ForwardRenderer/Data/ForwardRenderer.slang @@ -38,16 +38,6 @@ layout(binding = 0) cbuffer PerFrameCB : register(b0) float4x4 camVpAtLastCsmUpdate; float2 gRenderTargetDim; float gOpacityScale; - float hereIsATest[128]; - bool testBool; - bool2 testBool2; - bool3 testBool3; - bool4 testBool4[128]; -}; - -layout(binding = 8) cbuffer Tests : register(b0) -{ - float4x4 testMatrix; }; layout(set = 1, binding = 1) SamplerState gSampler; diff --git a/Samples/ForwardRenderer/ForwardRendererControls.cpp b/Samples/ForwardRenderer/ForwardRendererControls.cpp index 13b1c1f68..392be2f99 100644 --- a/Samples/ForwardRenderer/ForwardRendererControls.cpp +++ b/Samples/ForwardRenderer/ForwardRendererControls.cpp @@ -350,8 +350,5 @@ void ForwardRenderer::onGuiRender(SampleCallbacks* pSample, Gui* pGui) { applyLightingProgramControl(ControlID::EnableHashedAlpha); } - - mLightingPass.pVars->getConstantBuffer("PerFrameCB")->renderUI(pGui, "Constant Buffer: PerFrameCB"); - mLightingPass.pVars->getConstantBuffer("Tests")->renderUI(pGui, "Constant Buffer: Tests"); } } From b674040c46caf6dc8af782616d722a28b8c45e5b Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 2 Jul 2018 10:31:48 -0700 Subject: [PATCH 29/36] Fixes issues from pull request. Fixes gui for arrays again --- Framework/Source/API/ConstantBuffer.cpp | 7 ---- Framework/Source/API/ConstantBuffer.h | 8 ----- Framework/Source/API/VariablesBuffer.cpp | 7 ++++ Framework/Source/API/VariablesBuffer.h | 9 +++++ Framework/Source/Utils/Gui.cpp | 10 ++---- Framework/Source/Utils/VariablesBufferUI.cpp | 37 ++++++++++---------- Framework/Source/Utils/VariablesBufferUI.h | 13 ++----- 7 files changed, 40 insertions(+), 51 deletions(-) diff --git a/Framework/Source/API/ConstantBuffer.cpp b/Framework/Source/API/ConstantBuffer.cpp index da482ded0..9b1b7b844 100644 --- a/Framework/Source/API/ConstantBuffer.cpp +++ b/Framework/Source/API/ConstantBuffer.cpp @@ -35,7 +35,6 @@ #include "API/Device.h" #include "Renderer.h" -#include "Utils/VariablesBufferUI.h" namespace Falcor { @@ -85,10 +84,4 @@ namespace Falcor } return mpCbv; } - - void ConstantBuffer::renderUI(Gui* pGui, const char* uiGroup) - { - VariablesBufferUI variablesBufferUI(*this); - variablesBufferUI.renderUI(pGui, uiGroup); - } } \ No newline at end of file diff --git a/Framework/Source/API/ConstantBuffer.h b/Framework/Source/API/ConstantBuffer.h index f60ce9be0..5ccf7ac5e 100644 --- a/Framework/Source/API/ConstantBuffer.h +++ b/Framework/Source/API/ConstantBuffer.h @@ -35,8 +35,6 @@ namespace Falcor { class Sampler; - // Forward declares for gui draw func - class Gui; /** Abstracts a Constant/Uniform buffer. When accessing a variable by name, you can only use a name which points to a basic Type, or an array of basic Type (so if you want the start of a structure, ask for the first field in the struct). @@ -135,12 +133,6 @@ namespace Falcor return VariablesBuffer::setVariableArray(name, 0, pValue, count); } - /** Renders ui for reflected data within the buffer. - \param[in] pGui Pointer to the GUI structure for rendering - \param[in] uiGroup optional label for GUI - */ - void renderUI(Gui* pGui, const char* uiGroup = nullptr); - virtual bool uploadToGPU(size_t offset = 0, size_t size = -1) override; ConstantBufferView::SharedPtr getCbv() const; diff --git a/Framework/Source/API/VariablesBuffer.cpp b/Framework/Source/API/VariablesBuffer.cpp index 31d0414a2..d0fe68052 100644 --- a/Framework/Source/API/VariablesBuffer.cpp +++ b/Framework/Source/API/VariablesBuffer.cpp @@ -33,6 +33,7 @@ #include "Texture.h" #include "Graphics/Program/ProgramReflection.h" #include "API/Device.h" +#include "Utils/VariablesBufferUI.h" #include namespace Falcor @@ -393,4 +394,10 @@ namespace Falcor std::memcpy(mData.data() + offset, pSrc, size); mDirty = true; } + + void VariablesBuffer::renderUI(Gui* pGui, const char* uiGroup) + { + VariablesBufferUI variablesBufferUI(*this); + variablesBufferUI.renderUI(pGui, uiGroup); + } } diff --git a/Framework/Source/API/VariablesBuffer.h b/Framework/Source/API/VariablesBuffer.h index 06a8201cd..dea468a69 100644 --- a/Framework/Source/API/VariablesBuffer.h +++ b/Framework/Source/API/VariablesBuffer.h @@ -35,6 +35,8 @@ namespace Falcor { class Sampler; + // Forward declares for gui draw func + class Gui; /** Manages shader buffers containing named data, such as Constant/Uniform Buffers and Structured Buffers. When accessing a variable by name, you can only use a name which points to a basic Type, or an array of basic Type (so if you want the start of a structure, ask for the first field in the struct). @@ -80,6 +82,13 @@ namespace Falcor size_t getElementSize() const { return mElementSize; } + /** Renders ui for reflected data within the buffer. + \param[in] pGui Pointer to the GUI structure for rendering + \param[in] uiGroup optional label for GUI + */ + void renderUI(Gui* pGui, const char* uiGroup); + + // Allows UI functions to look through reflection data friend class VariablesBufferUI; protected: diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 8ea21d982..9a5c26ca8 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -280,8 +280,7 @@ namespace Falcor bool Gui::addCheckboxes(const char label[], bool* pData, uint32_t numCheckboxes, bool sameLine) { bool modified = false; - std::string labelString(std::string("##") + label); - labelString.push_back('0'); + std::string labelString(std::string("##") + label + '0'); for (uint32_t i = 0; i < numCheckboxes - 1; ++i) { @@ -289,9 +288,6 @@ namespace Falcor modified |= addCheckBox(labelString.c_str(), pData[i], (!i) ? sameLine : true); } - ImVec2 newCursorPosition = ImGui::GetCursorScreenPos(); - newCursorPosition.x += ImGui::GetContentRegionAvail().x; - ImGui::SetCursorScreenPos(newCursorPosition); addCheckBox(label, pData[numCheckboxes - 1], (numCheckboxes == 1) ? sameLine : true ); return modified; @@ -440,11 +436,11 @@ namespace Falcor hiddenLabelString[hiddenLabelString.size() - 2] = '0' + static_cast(i);\ if (i != var.length() - 1) \ { \ - b |= baseFunc (hiddenLabelString.c_str(), var[i], minVal, maxVal, sameLine);\ + b |= baseFunc (hiddenLabelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine);\ } \ else \ { \ - b |= baseFunc(labelString.c_str(), var[i], minVal, maxVal, sameLine); \ + b |= baseFunc(labelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); \ } \ if(i == 1) \ { \ diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp index 71d921c40..047e8e244 100644 --- a/Framework/Source/Utils/VariablesBufferUI.cpp +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -33,12 +33,12 @@ namespace Falcor { std::unordered_map VariablesBufferUI::mGuiArrayIndices; - bool VariablesBufferUI::renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name)//, std::vector& data) + bool renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name, std::vector& data) { bool returnValue = false; #define to_gui_widget(widgetName, baseType) \ - returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(mVariabelsBufferRef.mData.data() + offset)); \ + returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(data.data() + offset)); \ offset += sizeof(baseType); switch (type) @@ -132,7 +132,7 @@ namespace Falcor void VariablesBufferUI::renderUIMemberInternal(Gui* pGui, const std::string& memberName, size_t memberOffset, size_t memberSize, const std::string& memberTypeString, const ReflectionBasicType::Type& memberType, size_t arraySize) { // Display data from the stage memory - mVariabelsBufferRef.mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName); + mVariablesBufferRef.mDirty |= renderGuiWidgetFromType(pGui, memberType, memberOffset, memberName, mVariablesBufferRef.mData); // Display name and then reflection data as tooltip std::string toolTipString = "Offset: " + std::to_string(memberOffset); @@ -191,6 +191,15 @@ namespace Falcor const ReflectionBasicType* elementBasicType = pArrayType->getType()->asBasicType(); numMembers = pArrayType->getArraySize(); memberSize = pArrayType->getArrayStride(); + + // only iterate through array if it is displaying + if (pGui->beginGroup(memberName + "[" + std::to_string(numMembers) + "]")) + { + } + else + { + continue; + } if (elementBasicType) { @@ -225,9 +234,10 @@ namespace Falcor { // display information for specific index of array indexLabelString = (std::string("Index (Size : ") + std::to_string(numMembers) + ") "); - + pGui->addIntVar((std::string("##") + indexLabelString).c_str(), memberIndex, 0, static_cast(numMembers - 1)); + currentOffset += (memberSize * memberIndex); - displayName.append("[0:").append(std::to_string(numMembers)).append("]"); + displayName.append("[" + std::to_string(memberIndex) + ":" + std::to_string(numMembers) + "]"); } @@ -249,16 +259,7 @@ namespace Falcor if (numMembers > 1) { - if (pGui->addButton(("-##" + indexLabelString + displayName).c_str(), true)) - { - memberIndex--; - } - if (pGui->addButton(("+##" + indexLabelString + displayName).c_str(), true)) - { - memberIndex++; - } - - memberIndex = clamp(memberIndex, 0, static_cast(numMembers)); + pGui->endGroup(); } currentOffset += memberSize; @@ -267,15 +268,15 @@ namespace Falcor void VariablesBufferUI::renderUI(Gui* pGui, const char* uiGroup) { - const ReflectionStructType* pStruct = mVariabelsBufferRef.mpReflector->asResourceType()->getStructType()->asStructType(); + const ReflectionStructType* pStruct = mVariablesBufferRef.mpReflector->asResourceType()->getStructType()->asStructType(); if (!uiGroup || pGui->beginGroup(uiGroup)) { // begin recursion on first struct - renderUIInternal(pGui, pStruct, "", 0, mVariabelsBufferRef.mDirty); + renderUIInternal(pGui, pStruct, "", 0, mVariablesBufferRef.mDirty); // dirty flag for uploading will be set by GUI - mVariabelsBufferRef.uploadToGPU(); + mVariablesBufferRef.uploadToGPU(); pGui->endGroup(); } diff --git a/Framework/Source/Utils/VariablesBufferUI.h b/Framework/Source/Utils/VariablesBufferUI.h index 665bec12b..9ee20bcd6 100644 --- a/Framework/Source/Utils/VariablesBufferUI.h +++ b/Framework/Source/Utils/VariablesBufferUI.h @@ -38,24 +38,15 @@ namespace Falcor class VariablesBufferUI { public: - VariablesBufferUI(VariablesBuffer& variablesBufferRef) : mVariabelsBufferRef(variablesBufferRef) {} + VariablesBufferUI(VariablesBuffer& variablesBufferRef) : mVariablesBufferRef(variablesBufferRef) {} void renderUI(Gui* pGui, const char* uiGroup); private: - VariablesBuffer& mVariabelsBufferRef; + VariablesBuffer& mVariablesBufferRef; static std::unordered_map mGuiArrayIndices; - /** Call the corresponding gui function using the reflected data - \param[in] pGui Pointer to the gui structure for rendering - \param[in] type Reflection type to look up corresponding widget - \param[in] offset offset into the data array of the constant buffer - \param[in] name String name for widget to display - \return true if data was changed from the widget. internal used to call upload to gpu - */ - bool renderGuiWidgetFromType(Gui* pGui, ReflectionBasicType::Type type, size_t offset, const std::string& name); - /** Recursive function for traversing reflection data and display ui \param[in] pGui Pointer to the gui structure for rendering \param[in] pStruct Pointer to structure to iterate and display for the gui From 972d8831d76bc563afca4ea5d5d1365bd46b6bf9 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 2 Jul 2018 10:51:35 -0700 Subject: [PATCH 30/36] Fixes issue with modifying bool vectors again --- Framework/Source/Utils/Gui.cpp | 2 +- Framework/Source/Utils/VariablesBufferUI.cpp | 20 +++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 9a5c26ca8..4069eb897 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -288,7 +288,7 @@ namespace Falcor modified |= addCheckBox(labelString.c_str(), pData[i], (!i) ? sameLine : true); } - addCheckBox(label, pData[numCheckboxes - 1], (numCheckboxes == 1) ? sameLine : true ); + addCheckBox(label, pData[numCheckboxes - 1], true ); return modified; } diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp index 047e8e244..939507371 100644 --- a/Framework/Source/Utils/VariablesBufferUI.cpp +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -40,17 +40,25 @@ namespace Falcor #define to_gui_widget(widgetName, baseType) \ returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(data.data() + offset)); \ offset += sizeof(baseType); +#define to_gui_widget_bvec(widgetName, baseType) \ + { \ + uint32_t* pUintData = reinterpret_cast(data.data() + offset); \ + baseType tempBVec; \ + for (int32_t i = 0; i < tempBVec.length(); ++i) { tempBVec[i] = pUintData[i]; } \ + returnValue = pGui->concat_strings(add, widgetName)(name.c_str(), tempBVec); \ + for (int32_t i = 0; i < tempBVec.length(); ++i) { pUintData[i] = tempBVec[i]; offset += sizeof(uint32_t); } \ + } switch (type) { case ReflectionBasicType::Type::Bool4: - to_gui_widget(Bool4Var, glm::bvec4); + to_gui_widget_bvec(Bool4Var, glm::bvec4); break; case ReflectionBasicType::Type::Bool3: - to_gui_widget(Bool3Var, glm::bvec3); + to_gui_widget_bvec(Bool3Var, glm::bvec3); break; case ReflectionBasicType::Type::Bool2: - to_gui_widget(Bool2Var, glm::bvec2); + to_gui_widget_bvec(Bool2Var, glm::bvec2); break; case ReflectionBasicType::Type::Bool: to_gui_widget(CheckBox, bool); @@ -124,6 +132,7 @@ namespace Falcor should_not_get_here(); break; } +#undef to_gui_widget_bvec #undef to_gui_widget return returnValue; @@ -193,10 +202,7 @@ namespace Falcor memberSize = pArrayType->getArrayStride(); // only iterate through array if it is displaying - if (pGui->beginGroup(memberName + "[" + std::to_string(numMembers) + "]")) - { - } - else + if (!pGui->beginGroup(memberName + "[" + std::to_string(numMembers) + "]")) { continue; } From 8d81a6f85ba55358d5ce3144f4117e6e60c59d75 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 2 Jul 2018 11:55:44 -0700 Subject: [PATCH 31/36] Updated changelog. Removes include for imgui_internal. Adds label for arrays. --- CHANGELOG.md | 1 + Framework/Source/Utils/Gui.cpp | 24 +++++++++++++++----- Framework/Source/Utils/VariablesBufferUI.cpp | 2 +- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c71021b3..26e331c7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ v3.1 ------ - Added support for exporting BMP and TGA images. +- Added GUI for displaying and editing variable buffers. Call renderUI on buffer to display in gui. Bug Fixes: - Fixed crash when setting ForwardRenderer sample to MSAA with sample count 1 diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 4069eb897..52a2938fb 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -32,7 +32,6 @@ #include "Utils/UserInput.h" #include "API/RenderContext.h" #include "Externals/dear_imgui/imgui.h" -#include "Externals/dear_imgui/imgui_internal.h" #include "Utils/Math/FalcorMath.h" #include "glm/gtc/type_ptr.hpp" #include "Utils/StringUtils.h" @@ -436,22 +435,35 @@ namespace Falcor hiddenLabelString[hiddenLabelString.size() - 2] = '0' + static_cast(i);\ if (i != var.length() - 1) \ { \ - b |= baseFunc (hiddenLabelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine);\ + b |= baseFunc(hiddenLabelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine);\ } \ else \ { \ b |= baseFunc(labelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); \ } \ + if(i == 0) \ + { \ + ImGui::SameLine(); \ + bottomRight = ImGui::GetCursorScreenPos(); \ + float oldSpacing = ImGui::GetStyle().ItemSpacing.y; \ + ImGui::GetStyle().ItemSpacing.y = 0.0f; \ + ImGui::Dummy({}); \ + ImGui::Dummy({}); \ + ImGui::GetStyle().ItemSpacing.y = oldSpacing; \ + ImVec2 correctedCursorPos = ImGui::GetCursorScreenPos(); \ + correctedCursorPos.y += oldSpacing; \ + ImGui::SetCursorScreenPos(correctedCursorPos); \ + bottomRight.y = ImGui::GetCursorScreenPos().y; \ + } \ if(i == 1) \ { \ - bottomRight = ImGui::GetCurrentWindow()->DC.CursorPosPrevLine; \ bottomRight.y = topLeft.y + (bottomRight.y - topLeft.y) * (var.length()); \ - bottomRight.x -= ImGui::GetStyle().ItemInnerSpacing.x - 1; \ - bottomRight.y -= ImGui::GetStyle().ItemInnerSpacing.y - 1; \ + bottomRight.x -= ImGui::GetStyle().ItemInnerSpacing.x * 3 - 1; \ + bottomRight.y -= ImGui::GetStyle().ItemInnerSpacing.y - 1; \ topLeft.x -= 1; topLeft.y -= 1; \ auto colorVec4 =ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarGrab); colorVec4.w *= 0.25f; \ ImU32 color = ImGui::ColorConvertFloat4ToU32(colorVec4); \ - ImGui::GetCurrentWindow()->DrawList->AddRect(topLeft, bottomRight, color); \ + ImGui::GetOverlayDrawList()->AddRect(topLeft, bottomRight, color); \ } \ } \ return b;\ diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp index 939507371..0369793e2 100644 --- a/Framework/Source/Utils/VariablesBufferUI.cpp +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -240,7 +240,7 @@ namespace Falcor { // display information for specific index of array indexLabelString = (std::string("Index (Size : ") + std::to_string(numMembers) + ") "); - pGui->addIntVar((std::string("##") + indexLabelString).c_str(), memberIndex, 0, static_cast(numMembers - 1)); + pGui->addIntVar(("Array Index" + std::string("##") + indexLabelString).c_str(), memberIndex, 0, static_cast(numMembers - 1)); currentOffset += (memberSize * memberIndex); displayName.append("[" + std::to_string(memberIndex) + ":" + std::to_string(numMembers) + "]"); From d362d1c5cd869acc37232434036113afd21d4bba Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 2 Jul 2018 13:57:06 -0700 Subject: [PATCH 32/36] Converts macro gui function addMatrixVar to templated function. --- Framework/Source/Utils/Gui.cpp | 145 +++++++++++-------- Framework/Source/Utils/Gui.h | 23 +-- Framework/Source/Utils/VariablesBufferUI.cpp | 21 +-- 3 files changed, 109 insertions(+), 80 deletions(-) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 52a2938fb..9547330e6 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -417,68 +417,89 @@ namespace Falcor return b; } -#define add_matrix_function(funcName, matrixSize, baseFunc) \ - bool Gui::funcName(const char label[], concat_strings(glm::mat, matrixSize) & var, float minVal, float maxVal, bool sameLine) \ - { \ - std::string labelString(label); \ - std::string hiddenLabelString; \ - hiddenLabelString = "##" + labelString; \ - hiddenLabelString.append("[0]"); \ - \ - ImVec2 topLeft = ImGui::GetCursorScreenPos(); \ - ImVec2 bottomRight; \ - \ - bool b = false; \ - \ - for (uint32_t i = 0; i < static_cast(var.length()); ++i) \ - { \ - hiddenLabelString[hiddenLabelString.size() - 2] = '0' + static_cast(i);\ - if (i != var.length() - 1) \ - { \ - b |= baseFunc(hiddenLabelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine);\ - } \ - else \ - { \ - b |= baseFunc(labelString.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); \ - } \ - if(i == 0) \ - { \ - ImGui::SameLine(); \ - bottomRight = ImGui::GetCursorScreenPos(); \ - float oldSpacing = ImGui::GetStyle().ItemSpacing.y; \ - ImGui::GetStyle().ItemSpacing.y = 0.0f; \ - ImGui::Dummy({}); \ - ImGui::Dummy({}); \ - ImGui::GetStyle().ItemSpacing.y = oldSpacing; \ - ImVec2 correctedCursorPos = ImGui::GetCursorScreenPos(); \ - correctedCursorPos.y += oldSpacing; \ - ImGui::SetCursorScreenPos(correctedCursorPos); \ - bottomRight.y = ImGui::GetCursorScreenPos().y; \ - } \ - if(i == 1) \ - { \ - bottomRight.y = topLeft.y + (bottomRight.y - topLeft.y) * (var.length()); \ - bottomRight.x -= ImGui::GetStyle().ItemInnerSpacing.x * 3 - 1; \ - bottomRight.y -= ImGui::GetStyle().ItemInnerSpacing.y - 1; \ - topLeft.x -= 1; topLeft.y -= 1; \ - auto colorVec4 =ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarGrab); colorVec4.w *= 0.25f; \ - ImU32 color = ImGui::ColorConvertFloat4ToU32(colorVec4); \ - ImGui::GetOverlayDrawList()->AddRect(topLeft, bottomRight, color); \ - } \ - } \ - return b;\ - } - - add_matrix_function(addMatrix2x2Var, 2x2, addFloat2Var) - add_matrix_function(addMatrix2x3Var, 2x3, addFloat3Var) - add_matrix_function(addMatrix2x4Var, 2x4, addFloat4Var) - add_matrix_function(addMatrix3x2Var, 3x2, addFloat2Var) - add_matrix_function(addMatrix3x3Var, 3x3, addFloat3Var) - add_matrix_function(addMatrix3x4Var, 3x4, addFloat4Var) - add_matrix_function(addMatrix4x2Var, 4x2, addFloat2Var) - add_matrix_function(addMatrix4x3Var, 4x3, addFloat3Var) - add_matrix_function(addMatrix4x4Var, 4x4, addFloat4Var) -#undef add_matrix_function + template <> + bool Gui::addFloatVecVar(const char label[], glm::vec2& var, float minVal, float maxVal, float step, bool sameLine) + { + return addFloat2Var(label, var, minVal, maxVal, step, sameLine); + } + + template <> + bool Gui::addFloatVecVar(const char label[], glm::vec3& var, float minVal, float maxVal, float step, bool sameLine) + { + return addFloat3Var(label, var, minVal, maxVal, step, sameLine); + } + + template <> + bool Gui::addFloatVecVar(const char label[], glm::vec4& var, float minVal, float maxVal, float step, bool sameLine) + { + return addFloat4Var(label, var, minVal, maxVal, step, sameLine); + } + +#define add_matrix_var(TypeName) template bool Gui::addMatrixVar(const char label[], TypeName& var, float minVal , float maxVal, bool sameLine) + + add_matrix_var(glm::mat2x2); + add_matrix_var(glm::mat2x3); + add_matrix_var(glm::mat2x4); + add_matrix_var(glm::mat3x2); + add_matrix_var(glm::mat3x3); + add_matrix_var(glm::mat3x4); + add_matrix_var(glm::mat4x2); + add_matrix_var(glm::mat4x3); + add_matrix_var(glm::mat4x4); + +#undef add_matrix_var + + + template + bool Gui::addMatrixVar(const char label[], MatrixType& var, float minVal, float maxVal, bool sameLine) + { + std::string labelString(label); + std::string hiddenLabelString("##"); + hiddenLabelString += labelString + "[0]"; + + ImVec2 topLeft = ImGui::GetCursorScreenPos(); + ImVec2 bottomRight; + + bool b = false; + + for (uint32_t i = 0; i < static_cast(var.length()); ++i) + { + std::string& stringToDisplay = hiddenLabelString; + hiddenLabelString[hiddenLabelString.size() - 2] = '0' + static_cast(i); + if (i == var.length() - 1) + { + stringToDisplay = labelString; + } + + b |= addFloatVecVar(stringToDisplay.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); + + if (i == 0) + { + ImGui::SameLine(); + bottomRight = ImGui::GetCursorScreenPos(); + float oldSpacing = ImGui::GetStyle().ItemSpacing.y; + ImGui::GetStyle().ItemSpacing.y = 0.0f; + ImGui::Dummy({}); + ImGui::Dummy({}); + ImGui::GetStyle().ItemSpacing.y = oldSpacing; + ImVec2 correctedCursorPos = ImGui::GetCursorScreenPos(); + correctedCursorPos.y += oldSpacing; + ImGui::SetCursorScreenPos(correctedCursorPos); + bottomRight.y = ImGui::GetCursorScreenPos().y; + } + else if(i == 1) + { + bottomRight.y = topLeft.y + (bottomRight.y - topLeft.y) * (var.length()); + bottomRight.x -= ImGui::GetStyle().ItemInnerSpacing.x * 3 - 1; + bottomRight.y -= ImGui::GetStyle().ItemInnerSpacing.y - 1; + topLeft.x -= 1; topLeft.y -= 1; + auto colorVec4 =ImGui::GetStyleColorVec4(ImGuiCol_ScrollbarGrab); colorVec4.w *= 0.25f; + ImU32 color = ImGui::ColorConvertFloat4ToU32(colorVec4); + ImGui::GetOverlayDrawList()->AddRect(topLeft, bottomRight, color); + } + } + return b; + } bool Gui::addRgbColor(const char label[], glm::vec3& var, bool sameLine) { diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index 606874511..c2c9bce37 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -192,6 +192,9 @@ namespace Falcor bool addInt3Var(const char label[], glm::ivec3& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); bool addInt4Var(const char label[], glm::ivec4& var, int32_t minVal = -INT32_MAX, int32_t maxVal = INT32_MAX, bool sameLine = false); + template + bool addFloatVecVar(const char label[], VectorType& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, float step = 0.001f, bool sameLine = false); + /** Adds an matrix UI widget. \param[in] label The name of the widget. \param[in] var A reference to the matrix struct that will be updated directly when the widget state changes. @@ -200,15 +203,17 @@ namespace Falcor \param[in] sameLine Optional. If set to true, the widget will appear on the same line as the previous widget \return true if the value changed, otherwise false */ - bool addMatrix2x2Var(const char label[], glm::mat2x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix2x3Var(const char label[], glm::mat2x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix2x4Var(const char label[], glm::mat2x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix3x2Var(const char label[], glm::mat3x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix3x3Var(const char label[], glm::mat3x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix3x4Var(const char label[], glm::mat3x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix4x2Var(const char label[], glm::mat4x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix4x3Var(const char label[], glm::mat4x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - bool addMatrix4x4Var(const char label[], glm::mat4x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + template + bool addMatrixVar(const char label[], MatrixType& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + + // bool addMatrix2x3Var(const char label[], glm::mat2x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix2x4Var(const char label[], glm::mat2x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix3x2Var(const char label[], glm::mat3x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix3x3Var(const char label[], glm::mat3x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix3x4Var(const char label[], glm::mat3x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix4x2Var(const char label[], glm::mat4x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix4x3Var(const char label[], glm::mat4x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); + // bool addMatrix4x4Var(const char label[], glm::mat4x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); /** Add a separator */ diff --git a/Framework/Source/Utils/VariablesBufferUI.cpp b/Framework/Source/Utils/VariablesBufferUI.cpp index 0369793e2..e06141922 100644 --- a/Framework/Source/Utils/VariablesBufferUI.cpp +++ b/Framework/Source/Utils/VariablesBufferUI.cpp @@ -40,6 +40,9 @@ namespace Falcor #define to_gui_widget(widgetName, baseType) \ returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(data.data() + offset)); \ offset += sizeof(baseType); +#define to_gui_widget_matrix(widgetName, baseType) \ + returnValue = pGui-> concat_strings(add, widgetName)(name.c_str(), *reinterpret_cast(data.data() + offset)); \ + offset += sizeof(baseType); #define to_gui_widget_bvec(widgetName, baseType) \ { \ uint32_t* pUintData = reinterpret_cast(data.data() + offset); \ @@ -100,31 +103,31 @@ namespace Falcor to_gui_widget(Float4Var, glm::vec4); break; case ReflectionBasicType::Type::Float2x2: - to_gui_widget(Matrix2x2Var, glm::mat2x2); + to_gui_widget_matrix(MatrixVar, glm::mat2x2); break; case ReflectionBasicType::Type::Float2x3: - to_gui_widget(Matrix2x3Var, glm::mat2x3); + to_gui_widget_matrix(MatrixVar, glm::mat2x3); break; case ReflectionBasicType::Type::Float2x4: - to_gui_widget(Matrix2x4Var, glm::mat2x4); + to_gui_widget_matrix(MatrixVar, glm::mat2x4); break; case ReflectionBasicType::Type::Float3x2: - to_gui_widget(Matrix3x2Var, glm::mat3x2); + to_gui_widget_matrix(MatrixVar, glm::mat3x2); break; case ReflectionBasicType::Type::Float3x3: - to_gui_widget(Matrix3x3Var, glm::mat3x3); + to_gui_widget_matrix(MatrixVar, glm::mat3x3); break; case ReflectionBasicType::Type::Float3x4: - to_gui_widget(Matrix3x4Var, glm::mat3x4); + to_gui_widget_matrix(MatrixVar, glm::mat3x4); break; case ReflectionBasicType::Type::Float4x2: - to_gui_widget(Matrix4x2Var, glm::mat4x2); + to_gui_widget_matrix(MatrixVar, glm::mat4x2); break; case ReflectionBasicType::Type::Float4x3: - to_gui_widget(Matrix4x3Var, glm::mat4x3); + to_gui_widget_matrix(MatrixVar, glm::mat4x3); break; case ReflectionBasicType::Type::Float4x4: - to_gui_widget(Matrix4x4Var, glm::mat4x4); + to_gui_widget_matrix(MatrixVar, glm::mat4x4); break; case ReflectionBasicType::Type::Unknown: break; From b2e8fcdab7a76c51d1fa0b849eac6713ad7c4847 Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Mon, 2 Jul 2018 13:57:48 -0700 Subject: [PATCH 33/36] Converts macro gui function addMatrixVar to templated function. --- Framework/Source/Utils/Gui.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/Framework/Source/Utils/Gui.h b/Framework/Source/Utils/Gui.h index c2c9bce37..16bbb652c 100644 --- a/Framework/Source/Utils/Gui.h +++ b/Framework/Source/Utils/Gui.h @@ -206,15 +206,6 @@ namespace Falcor template bool addMatrixVar(const char label[], MatrixType& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix2x3Var(const char label[], glm::mat2x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix2x4Var(const char label[], glm::mat2x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix3x2Var(const char label[], glm::mat3x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix3x3Var(const char label[], glm::mat3x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix3x4Var(const char label[], glm::mat3x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix4x2Var(const char label[], glm::mat4x2& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix4x3Var(const char label[], glm::mat4x3& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - // bool addMatrix4x4Var(const char label[], glm::mat4x4& var, float minVal = -FLT_MAX, float maxVal = FLT_MAX, bool sameLine = false); - /** Add a separator */ void addSeparator(); From 1da3dbe505f17625faafa82dcbc57159aee6cfcf Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Mon, 9 Jul 2018 17:36:36 -0700 Subject: [PATCH 34/36] Updated Version and Changelog --- CHANGELOG.md | 3 ++- Framework/Source/Falcor.h | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1c5503a33..a29eb89e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -v3.1 +v3.0.5 ------ - Added support for exporting BMP and TGA images. - Added `ConstantBuffer::renderUI()` to automatically render UI for editing a constant buffer's values. @@ -6,6 +6,7 @@ v3.1 Bug Fixes: - Fixed crash when setting ForwardRenderer sample to MSAA with sample count 1 - std::string version of Gui::addTextBox() now correctly updates the user's string +- Fixed row-pitch calculation when copying texture subresources in DX12 v3.0.4 ------ diff --git a/Framework/Source/Falcor.h b/Framework/Source/Falcor.h index 6da21594f..334262a26 100644 --- a/Framework/Source/Falcor.h +++ b/Framework/Source/Falcor.h @@ -158,7 +158,7 @@ #endif #define FALCOR_MAJOR_VERSION 3 -#define FALCOR_MINOR_VERSION 1 +#define FALCOR_MINOR_VERSION 0 #define FALCOR_DEV_STAGE "" -#define FALCOR_DEV_REVISION 0 -#define FALCOR_VERSION_STRING "3.1" \ No newline at end of file +#define FALCOR_DEV_REVISION 5 +#define FALCOR_VERSION_STRING "3.0.5" \ No newline at end of file From 73d68e5471018d587cd3d4e65049af70b3b30034 Mon Sep 17 00:00:00 2001 From: Kai-Hwa Yao Date: Tue, 10 Jul 2018 12:55:54 -0700 Subject: [PATCH 35/36] Updated DXR instructions in README --- README.md | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index c16ef0929..09ae20004 100644 --- a/README.md +++ b/README.md @@ -11,25 +11,26 @@ Its features include: Prerequisites ------------------------ - GPU that supports DirectX 12 or Vulkan -- Windows 10 RS2 (1703 Creators Update) or newer, or Ubuntu 17.10 +- Windows 10 RS2 (version 1703) or newer, or Ubuntu 17.10 On Windows: - Visual Studio 2017 - [Microsoft Windows SDK ver 10.0.15063.468](https://developer.microsoft.com/en-us/windows/downloads/sdk-archive) -- Windows 10 -- GPU that supports DirectX 12 or Vulkan - To run DirectX 12 applications with the debug layer enabled, you need to install the Graphics Tools optional feature. The tools version must match the OS version you are using (not to be confused with the SDK version used for building Falcor). There are 2 ways to install it: - - Click the Windows button and type `Optional Features`, in the window that openes click `Add a feature` and select `Graphics Tools`. + - Click the Windows button and type `Optional Features`, in the window that opens click `Add a feature` and select `Graphics Tools`. - Download an offline pacakge from [here](https://docs.microsoft.com/en-us/windows-hardware/test/hlk/windows-hardware-lab-kit#supplemental-content-for-graphics-media-and-mean-time-between-failures-mtbf-tests). Choose a ZIP file that matches the OS version you are using. The ZIP includes a document which explains how to install the graphics tools. - + DirectX Raytracing ------------------------- -Falcor 3.0 adds support to DirectX Raytracing. It adds 2 new build configurations - `ReleaseDXR` and `DebugDXR`. These are the only configurations which will build the DXR abstraction layer. +Falcor 3.0 adds support for DirectX Raytracing. It adds 2 new build configurations - `ReleaseDXR` and `DebugDXR`. These are the only configurations which will build the DXR abstraction layer. The HelloDXR sample demonstrates how to use Falcor’s DXR abstraction layer. -Requirements: -- Windows RS4 - Follow the instructions on http://forums.directxtech.com/index.php?topic=5860.0. -- You do not need to download the DXR SDK yourself, it is packaged with Falcor. -- A GPU which supports DirectX Raytracing, such as GeForce Titan-V (make sure you have the latest driver) + +- Requirements: + - Windows 10 RS4 (version 1804) + - Windows 10 Developer Mode enabled (Windows Settings -> Update & Security -> For developers -> Developer mode) + - You do not need to download the DXR SDK yourself, it is packaged with Falcor. + - A GPU which supports DirectX Raytracing, such as the NVIDIA Titan V + - NVIDIA driver version 397.31 or later Currently, Falcor doesn’t support the DXR fallback layer. We will add support for it in the near future. Please note that the DXR abstraction layer is considererd an experimental feature, just like DXR itself. The interfaces and features might change in future releases. From e672342810752638a3eb21161e6ad479f169a74b Mon Sep 17 00:00:00 2001 From: Matthew Oakes Date: Tue, 10 Jul 2018 15:28:16 -0700 Subject: [PATCH 36/36] Fixed template error for linux builds --- Framework/Source/Utils/Gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Framework/Source/Utils/Gui.cpp b/Framework/Source/Utils/Gui.cpp index 9547330e6..c34544dc1 100644 --- a/Framework/Source/Utils/Gui.cpp +++ b/Framework/Source/Utils/Gui.cpp @@ -471,7 +471,7 @@ namespace Falcor stringToDisplay = labelString; } - b |= addFloatVecVar(stringToDisplay.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); + b |= addFloatVecVar(stringToDisplay.c_str(), var[i], minVal, maxVal, 0.001f, sameLine); if (i == 0) {