From 5d6b1181a51bb43572764581f30adf35eb31101b Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Fri, 28 Mar 2025 17:43:02 +0000 Subject: [PATCH 1/3] Add vsgincompatiblepipelinelayouts example --- data/shaders/custom_pbr.frag | 16 +- examples/utils/CMakeLists.txt | 1 + .../CMakeLists.txt | 15 ++ .../custom_pbr.cpp | 84 +++++++ .../custom_pbr.h | 79 ++++++ .../vsgincompatiblepipelinelayouts.cpp | 235 ++++++++++++++++++ 6 files changed, 429 insertions(+), 1 deletion(-) create mode 100644 examples/utils/vsgincompatiblepipelinelayouts/CMakeLists.txt create mode 100644 examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.cpp create mode 100644 examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.h create mode 100644 examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp diff --git a/data/shaders/custom_pbr.frag b/data/shaders/custom_pbr.frag index 8d9d78a7..a80497a4 100644 --- a/data/shaders/custom_pbr.frag +++ b/data/shaders/custom_pbr.frag @@ -1,6 +1,6 @@ #version 450 #extension GL_ARB_separate_shader_objects : enable -#pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_DETAIL_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, VSG_SHADOWS_PCSS, VSG_SHADOWS_SOFT, VSG_SHADOWS_HARD, SHADOWMAP_DEBUG, VSG_ALPHA_TEST) +#pragma import_defines (VSG_POINT_SPRITE, VSG_DIFFUSE_MAP, VSG_GREYSCALE_DIFFUSE_MAP, VSG_DETAIL_MAP, VSG_EMISSIVE_MAP, VSG_LIGHTMAP_MAP, VSG_NORMAL_MAP, VSG_METALLROUGHNESS_MAP, VSG_SPECULAR_MAP, VSG_TWO_SIDED_LIGHTING, VSG_WORKFLOW_SPECGLOSS, VSG_SHADOWS_PCSS, VSG_SHADOWS_SOFT, VSG_SHADOWS_HARD, SHADOWMAP_DEBUG, VSG_ALPHA_TEST, CUSTOM_HIGHLIGHT) // define by default for backwards compatibility #define VSG_SHADOWS_HARD @@ -8,6 +8,7 @@ #define VIEW_DESCRIPTOR_SET 1 #define MATERIAL_DESCRIPTOR_SET 2 #define CUSTOM_DESCRIPTOR_SET 0 +#define HIGHLIGHT_DESCRIPTOR_SET 3 const float PI = 3.14159265359; const float RECIPROCAL_PI = 0.31830988618; @@ -72,6 +73,14 @@ layout(set = CUSTOM_DESCRIPTOR_SET, binding = 0) uniform Fog float exponent; } fog; +#ifdef CUSTOM_HIGHLIGHT +layout(set = HIGHLIGHT_DESCRIPTOR_SET, binding = 0) uniform Highlight +{ + vec3 color; + bool highlighted; +} highlight; +#endif + layout(location = 0) in vec3 eyePos; layout(location = 1) in vec3 normalDir; layout(location = 2) in vec4 vertexColor; @@ -581,5 +590,10 @@ void main() } } +#ifdef CUSTOM_HIGHLIGHT + if (highlight.highlighted) + color += highlight.color; +#endif + outColor = vec4(color, baseColor.a); } diff --git a/examples/utils/CMakeLists.txt b/examples/utils/CMakeLists.txt index 1e080732..137a9464 100644 --- a/examples/utils/CMakeLists.txt +++ b/examples/utils/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(vsgbuilder) add_subdirectory(vsggraphicspipelineconfigurator) add_subdirectory(vsgshaderset) +add_subdirectory(vsgincompatiblepipelinelayouts) add_subdirectory(vsgintersection) add_subdirectory(vsgstoragebuffer) add_subdirectory(vsgcustomshaderset) diff --git a/examples/utils/vsgincompatiblepipelinelayouts/CMakeLists.txt b/examples/utils/vsgincompatiblepipelinelayouts/CMakeLists.txt new file mode 100644 index 00000000..63b1fcc3 --- /dev/null +++ b/examples/utils/vsgincompatiblepipelinelayouts/CMakeLists.txt @@ -0,0 +1,15 @@ +set(SOURCES + custom_pbr.cpp + vsgincompatiblepipelinelayouts.cpp +) + +add_executable(vsgincompatiblepipelinelayouts ${SOURCES}) + +target_link_libraries(vsgincompatiblepipelinelayouts vsg::vsg) + +if (vsgXchange_FOUND) + target_compile_definitions(vsgincompatiblepipelinelayouts PRIVATE vsgXchange_FOUND) + target_link_libraries(vsgincompatiblepipelinelayouts vsgXchange::vsgXchange) +endif() + +install(TARGETS vsgincompatiblepipelinelayouts RUNTIME DESTINATION bin) diff --git a/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.cpp b/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.cpp new file mode 100644 index 00000000..4ab2a699 --- /dev/null +++ b/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.cpp @@ -0,0 +1,84 @@ +/* + +Copyright(c) 2020 Robert Osfield + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "custom_pbr.h" + +vsg::RegisterWithObjectFactoryProxy s_Register_FogValue; +vsg::RegisterWithObjectFactoryProxy s_Register_HighlightValue; + +vsg::ref_ptr custom::pbr_ShaderSet(vsg::ref_ptr options) +{ + vsg::info("Local pbr_ShaderSet(", options, ")"); + + auto vertexShader = vsg::read_cast("shaders/custom_pbr.vert", options); + auto fragmentShader = vsg::read_cast("shaders/custom_pbr.frag", options); + + if (!vertexShader || !fragmentShader) + { + vsg::error("pbr_ShaderSet(...) could not find shaders."); + return {}; + } + +#define VIEW_DESCRIPTOR_SET 1 +#define MATERIAL_DESCRIPTOR_SET 2 +#define CUSTOM_DESCRIPTOR_SET 0 +#define HIGHLIGHT_DESCRIPTOR_SET 3 + + auto shaderSet = vsg::ShaderSet::create(vsg::ShaderStages{vertexShader, fragmentShader}); + + shaderSet->addAttributeBinding("vsg_Vertex", "", 0, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_Normal", "", 1, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_TexCoord0", "", 2, VK_FORMAT_R32G32_SFLOAT, vsg::vec2Array::create(1)); + shaderSet->addAttributeBinding("vsg_Color", "", 3, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); + + shaderSet->addAttributeBinding("vsg_position", "VSG_INSTANCE_POSITIONS", 4, VK_FORMAT_R32G32B32_SFLOAT, vsg::vec3Array::create(1)); + shaderSet->addAttributeBinding("vsg_position_scaleDistance", "VSG_BILLBOARD", 4, VK_FORMAT_R32G32B32A32_SFLOAT, vsg::vec4Array::create(1)); + + shaderSet->addDescriptorBinding("displacementMap", "VSG_DISPLACEMENT_MAP", MATERIAL_DESCRIPTOR_SET, 6, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_VERTEX_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("diffuseMap", "VSG_DIFFUSE_MAP", MATERIAL_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("mrMap", "VSG_METALLROUGHNESS_MAP", MATERIAL_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec2Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32_SFLOAT})); + shaderSet->addDescriptorBinding("normalMap", "VSG_NORMAL_MAP", MATERIAL_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec3Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32G32B32_SFLOAT})); + shaderSet->addDescriptorBinding("aoMap", "VSG_LIGHTMAP_MAP", MATERIAL_DESCRIPTOR_SET, 3, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + shaderSet->addDescriptorBinding("emissiveMap", "VSG_EMISSIVE_MAP", MATERIAL_DESCRIPTOR_SET, 4, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("specularMap", "VSG_SPECULAR_MAP", MATERIAL_DESCRIPTOR_SET, 5, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::ubvec4Array2D::create(1, 1, vsg::Data::Properties{VK_FORMAT_R8G8B8A8_UNORM})); + shaderSet->addDescriptorBinding("material", "", MATERIAL_DESCRIPTOR_SET, 10, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::PbrMaterialValue::create()); + + shaderSet->addDescriptorBinding("lightData", "", VIEW_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Array::create(64)); + shaderSet->addDescriptorBinding("viewportData", "", VIEW_DESCRIPTOR_SET, 1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, vsg::vec4Value::create(0, 0, 1280, 1024)); + shaderSet->addDescriptorBinding("shadowMaps", "", VIEW_DESCRIPTOR_SET, 2, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, vsg::floatArray3D::create(1, 1, 1, vsg::Data::Properties{VK_FORMAT_R32_SFLOAT})); + + shaderSet->addDescriptorBinding("Fog", "", CUSTOM_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, custom::FogValue::create()); + + shaderSet->addDescriptorBinding("highlight", "CUSTOM_HIGHLIGHT", HIGHLIGHT_DESCRIPTOR_SET, 0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, 1, VK_SHADER_STAGE_FRAGMENT_BIT, nullptr); + + // additional defines + shaderSet->optionalDefines = {"VSG_GREYSCALE_DIFFUSE_MAP", "VSG_TWO_SIDED_LIGHTING", "VSG_WORKFLOW_SPECGLOSS"}; + + shaderSet->addPushConstantRange("pc", "", VK_SHADER_STAGE_ALL, 0, 128); + + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_INSTANCE_POSITIONS", "VSG_DISPLACEMENT_MAP"}, vsg::PositionAndDisplacementMapArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_INSTANCE_POSITIONS"}, vsg::PositionArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_DISPLACEMENT_MAP"}, vsg::DisplacementMapArrayState::create()}); + shaderSet->definesArrayStates.push_back(vsg::DefinesArrayState{{"VSG_BILLBOARD"}, vsg::BillboardArrayState::create()}); + + shaderSet->customDescriptorSetBindings.push_back(vsg::ViewDependentStateBinding::create(VIEW_DESCRIPTOR_SET)); + + return shaderSet; +} diff --git a/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.h b/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.h new file mode 100644 index 00000000..34938872 --- /dev/null +++ b/examples/utils/vsgincompatiblepipelinelayouts/custom_pbr.h @@ -0,0 +1,79 @@ +#pragma once + +#include + +namespace custom +{ + // OpenGL style fog struct to pass to the GPU + struct Fog + { + vsg::vec3 color = {1.0f, 1.0f, 1.0f}; + float density = 0.0005f; // OpenGL default is 1.0! + float start = 0.0f; + float end = 1.0f; + float exponent = 1.0f; + + void read(vsg::Input& input) + { + input.read("color", color); + input.read("density", density); + input.read("start", start); + input.read("end", end); + input.read("exponent", exponent); + } + + void write(vsg::Output& output) const + { + output.write("color", color); + output.write("density", density); + output.write("start", start); + output.write("end", end); + output.write("exponent", exponent); + } + }; + + using FogValue = vsg::Value; + + struct Highlight + { + vsg::vec3 color = {0.2f, 0.2f, 0.0f}; + bool highlighted = false; + + Highlight() = default; + Highlight(bool in_highlighted) + : highlighted(in_highlighted) + {} + + void read(vsg::Input& input) + { + input.read("highlighted", highlighted); + input.read("color", color); + } + + void write(vsg::Output& output) const + { + output.write("highlighted", highlighted); + output.write("color", color); + } + }; + + using HighlightValue = vsg::Value; + + extern vsg::ref_ptr pbr_ShaderSet(vsg::ref_ptr options); +} // namespace custom + +template<> +constexpr bool vsg::has_read_write() +{ + return true; +} + +EVSG_type_name(custom::FogValue); + +template<> +constexpr bool vsg::has_read_write() +{ + return true; +} + +EVSG_type_name(custom::HighlightValue); diff --git a/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp new file mode 100644 index 00000000..d1e514c1 --- /dev/null +++ b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp @@ -0,0 +1,235 @@ +#include +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +#include "custom_pbr.h" + +int main(int argc, char** argv) +{ + // use the vsg::Options object to pass the ReaderWriter_all to use when reading files. + auto options = vsg::Options::create(); +#ifdef vsgXchange_FOUND + options->add(vsgXchange::all::create()); +#endif + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + options->sharedObjects = vsg::SharedObjects::create(); + + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + // read any command line options that the ReaderWriters support + arguments.read(options); + + auto windowTraits = vsg::WindowTraits::create(); + windowTraits->windowTitle = "vsgincompatiblepipelinelayouts"; + windowTraits->debugLayer = arguments.read({"--debug", "-d"}); + windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); + windowTraits->synchronizationLayer = arguments.read("--sync"); + + auto numFrames = arguments.value(-1, "-f"); + auto outputFilename = arguments.value("", "-o"); + auto horizonMountainHeight = arguments.value(0.0, "--hmh"); + auto nearFarRatio = arguments.value(0.001, "--nfr"); + bool reportAverageFrameRate = arguments.read("--fps"); + bool inherit = arguments.read("--inherit"); + bool layer = arguments.read("--text-layer"); + bool highlight = arguments.read("--highlight"); + bool first = arguments.read("--first"); + bool last = arguments.read("--last"); + + vsg::ref_ptr customShaderSet = custom::pbr_ShaderSet(options); + if (highlight) + { + if (!customShaderSet->defaultShaderHints) + customShaderSet->defaultShaderHints = vsg::ShaderCompileSettings::create(); + customShaderSet->defaultShaderHints->defines.insert("CUSTOM_HIGHLIGHT"); + } + options->shaderSets["pbr"] = customShaderSet; + if (!customShaderSet) + { + std::cout << "No vsg::ShaderSet to process." << std::endl; + return 1; + } + + const auto& defines = customShaderSet->defaultShaderHints ? customShaderSet->defaultShaderHints->defines : std::set{}; + + bool fogSet = false; + auto fogValue = custom::FogValue::create(); + auto& fog = fogValue->value(); + fogSet = arguments.read("--color", fog.color) || fogSet; + fogSet = arguments.read("--start", fog.start) || fogSet; + fogSet = arguments.read("--end", fog.end) || fogSet; + fogSet = arguments.read("--exponent", fog.exponent) || fogSet; + fogSet = arguments.read("--density", fog.density) || fogSet; + + if (fogSet && !inherit) + { + // change the default data to the local fogValue we've been assigning values to + auto& fogBinding = customShaderSet->getDescriptorBinding("Fog"); + if (fogBinding.name == "Fog") + { + fogBinding.data = fogValue; + vsg::info("Setting default fog to ", fogValue); + } + } + + auto vsg_scene = vsg::StateGroup::create(); + + auto layout = customShaderSet->createPipelineLayout(defines, {0, 4}); + + uint32_t highlight_set = 3; + auto highlight_dsl = customShaderSet->createDescriptorSetLayout(defines, highlight_set); + + if (inherit) + { + // + // place the FogValue DescriptorSet at the root of the scene graph + // and optionally tell the loader via vsg::Options::inheritedState that it doesn't need to assign + // it to subgraphs that loader will create + // + uint32_t cm_set = 0; + auto cm_dsl = customShaderSet->createDescriptorSetLayout(defines, cm_set); + auto cm_db = vsg::DescriptorBuffer::create(fogValue); + auto cm_ds = vsg::DescriptorSet::create(cm_dsl, vsg::Descriptors{cm_db}); + auto cm_bds = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, cm_set, cm_ds); + vsg_scene->add(cm_bds); + + uint32_t vds_set = 1; + vsg_scene->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); + + vsg::info("Added state to inherit "); + options->inheritedState = vsg_scene->stateCommands; + } + + // read any vsg files + for (int i = 1; i < argc; ++i) + { + vsg::Path filepath = arguments[i]; + auto group = vsg::StateGroup::create(); + + if (highlight) + { + auto highlight_db = vsg::DescriptorBuffer::create(custom::HighlightValue::create(custom::Highlight{i % 2 == 1})); + auto highlight_ds = vsg::DescriptorSet::create(highlight_dsl, vsg::Descriptors{highlight_db}); + auto highlight_bds = vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, highlight_set, highlight_ds); + group->add(highlight_bds); + } + + vsg::ref_ptr node; + if (node = vsg::read_cast(filepath, options)) + { + if (first) + group->addChild(node); + } + else + { + std::cout << "Unable to load file " << filepath << std::endl; + } + + auto text = vsg::Text::create(); + text->font = vsg::read_cast("fonts/times.vsgb", options); + auto layout = vsg::StandardLayout::create(); + layout->billboard = true; + text->layout = layout; + std::string filename = filepath.string(); + auto filenameStart = filename.find_last_of("\\/"); + if (filenameStart != std::string::npos) + filename = filename.substr(filenameStart + 1); + text->text = vsg::stringValue::create(filename); + text->setup(0, options); + if (layer) + { + auto layer = vsg::Layer::create(); + layer->child = text; + group->addChild(layer); + } + else + group->addChild(text); + + if (node && last) + { + group->addChild(node); + } + + vsg_scene->addChild(group); + } + + if (vsg_scene->children.empty()) + { + return 1; + } + + if (outputFilename) + { + vsg::write(vsg_scene, outputFilename, options); + } + + // create the viewer and assign window(s) to it + auto viewer = vsg::Viewer::create(); + auto window = vsg::Window::create(windowTraits); + if (!window) + { + std::cout << "Could not create window." << std::endl; + return 1; + } + + viewer->addWindow(window); + + // compute the bounds of the scene graph to help position camera + auto bounds = vsg::visit(vsg_scene).bounds; + vsg::dvec3 centre = (bounds.min + bounds.max) * 0.5; + double radius = vsg::length(bounds.max - bounds.min) * 0.6; + + vsg::info("scene bounds ", bounds); + + // set up the camera + auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); + + vsg::ref_ptr perspective; + auto ellipsoidModel = vsg_scene->getRefObject("EllipsoidModel"); + if (ellipsoidModel) + { + perspective = vsg::EllipsoidPerspective::create(lookAt, ellipsoidModel, 30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio, horizonMountainHeight); + } + else + { + perspective = vsg::Perspective::create(30.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 4.5); + } + + auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D())); + + // add close handler to respond to the close window button and pressing escape + viewer->addEventHandler(vsg::CloseHandler::create(viewer)); + viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + + auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); + viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + + viewer->compile(); + + viewer->start_point() = vsg::clock::now(); + + // rendering main loop + while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) + { + // pass any events into EventHandlers assigned to the Viewer + viewer->handleEvents(); + + viewer->update(); + + viewer->recordAndSubmit(); + + viewer->present(); + } + + if (reportAverageFrameRate) + { + auto fs = viewer->getFrameStamp(); + double fps = static_cast(fs->frameCount) / std::chrono::duration(vsg::clock::now() - viewer->start_point()).count(); + std::cout << "Average frame rate = " << fps << " fps" << std::endl; + } + return 0; +} From 0639e149c7592a466a06239cbbaf2c6a9f9706b7 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Thu, 3 Apr 2025 18:10:37 +0100 Subject: [PATCH 2/3] Avoid shadowing --- .../vsgincompatiblepipelinelayouts.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp index d1e514c1..c63cba43 100644 --- a/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp +++ b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp @@ -131,9 +131,9 @@ int main(int argc, char** argv) auto text = vsg::Text::create(); text->font = vsg::read_cast("fonts/times.vsgb", options); - auto layout = vsg::StandardLayout::create(); - layout->billboard = true; - text->layout = layout; + auto textLayout = vsg::StandardLayout::create(); + textLayout->billboard = true; + text->layout = textLayout; std::string filename = filepath.string(); auto filenameStart = filename.find_last_of("\\/"); if (filenameStart != std::string::npos) From 161b9c4ff86af2e1c150efca8f96bad76fd370f2 Mon Sep 17 00:00:00 2001 From: AnyOldName3 Date: Wed, 9 Apr 2025 16:18:35 +0100 Subject: [PATCH 3/3] Add highlight to inherited state --- .../vsgincompatiblepipelinelayouts.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp index c63cba43..c90d68cb 100644 --- a/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp +++ b/examples/utils/vsgincompatiblepipelinelayouts/vsgincompatiblepipelinelayouts.cpp @@ -101,7 +101,14 @@ int main(int argc, char** argv) vsg_scene->add(vsg::BindViewDescriptorSets::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, vds_set)); vsg::info("Added state to inherit "); - options->inheritedState = vsg_scene->stateCommands; + if (highlight) + { + // Copy the container so we can add more inherited state without setting an overall value for the whole scenegraph + options->inheritedState = vsg::StateCommands(vsg_scene->stateCommands); + options->inheritedState.push_back(vsg::BindDescriptorSet::create(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, highlight_set, nullptr)); + } + else + options->inheritedState = vsg_scene->stateCommands; } // read any vsg files