From 003567673494fbe9832fde811149d0dc035f8da1 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Oct 2025 17:48:08 +0000 Subject: [PATCH 01/15] Created vsgsampler example to illustrate effect of mipmapping/user of vsg::Sampler --- examples/state/CMakeLists.txt | 1 + examples/state/vsgsampler/CMakeLists.txt | 12 ++ examples/state/vsgsampler/vsgsampler.cpp | 214 +++++++++++++++++++++++ 3 files changed, 227 insertions(+) create mode 100644 examples/state/vsgsampler/CMakeLists.txt create mode 100644 examples/state/vsgsampler/vsgsampler.cpp diff --git a/examples/state/CMakeLists.txt b/examples/state/CMakeLists.txt index f19a3a29..cb84ceee 100644 --- a/examples/state/CMakeLists.txt +++ b/examples/state/CMakeLists.txt @@ -6,6 +6,7 @@ add_subdirectory(vsgcomputevertex) add_subdirectory(vsgdynamicvertex) add_subdirectory(vsgclip) add_subdirectory(vsgextendstate) +add_subdirectory(vsgsampler) if (vsgImGui_FOUND) add_subdirectory(vsgdynamicstate) diff --git a/examples/state/vsgsampler/CMakeLists.txt b/examples/state/vsgsampler/CMakeLists.txt new file mode 100644 index 00000000..2d807e39 --- /dev/null +++ b/examples/state/vsgsampler/CMakeLists.txt @@ -0,0 +1,12 @@ +set(SOURCES vsgsampler.cpp) + +add_executable(vsgsampler ${SOURCES}) + +target_link_libraries(vsgsampler vsg::vsg) + +if (vsgXchange_FOUND) + target_compile_definitions(vsgsampler PRIVATE vsgXchange_FOUND) + target_link_libraries(vsgsampler vsgXchange::vsgXchange) +endif() + +install(TARGETS vsgsampler RUNTIME DESTINATION bin) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp new file mode 100644 index 00000000..869502ea --- /dev/null +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -0,0 +1,214 @@ +#include +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +// +vsg::ref_ptr createTexturedQuad(const vsg::vec3& position, const vsg::vec2& extents, vsg::ref_ptr textureData, vsg::ref_ptr sampler, vsg::ref_ptr options) +{ + auto sharedObjects = options->sharedObjects; + auto shaderSet = vsg::createFlatShadedShaderSet(options); + auto graphicsPipelineConfig = vsg::GraphicsPipelineConfigurator::create(shaderSet); + + // enable texturing + graphicsPipelineConfig->assignTexture("diffuseMap", textureData, sampler); + + // set up vertex and index arrays + auto vertices = vsg::vec3Array::create( + {position, + position + vsg::vec3(extents.x, 0.0f, 0.0f), + position + vsg::vec3(extents.x, 0.0f, extents.y), + position + vsg::vec3(0.0f, 0.0f, extents.y) + }); + + auto normals = vsg::vec3Array::create( + {{0.0f, -1.0f, 0.0f} + }); + + auto texcoords = vsg::vec2Array::create( + {{0.0f, 1.0f}, + {1.0f, 1.0f}, + {1.0f, 0.0f}, + {0.0f, 0.0f} + }); + + auto colors = vsg::vec4Value::create(vsg::vec4{1.0f, 1.0f, 1.0f, 1.0f}); + + auto indices = vsg::ushortArray::create( + {0, 1, 2, + 2, 3, 0}); + + vsg::DataList vertexArrays; + + graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Vertex", VK_VERTEX_INPUT_RATE_VERTEX, vertices); + graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Normal", VK_VERTEX_INPUT_RATE_INSTANCE, normals); + graphicsPipelineConfig->assignArray(vertexArrays, "vsg_TexCoord0", VK_VERTEX_INPUT_RATE_VERTEX, texcoords); + graphicsPipelineConfig->assignArray(vertexArrays, "vsg_Color", VK_VERTEX_INPUT_RATE_INSTANCE, colors); + + if (sharedObjects) sharedObjects->share(vertexArrays); + if (sharedObjects) sharedObjects->share(indices); + + // setup geometry + auto drawCommands = vsg::Commands::create(); + drawCommands->addChild(vsg::BindVertexBuffers::create(graphicsPipelineConfig->baseAttributeBinding, vertexArrays)); + drawCommands->addChild(vsg::BindIndexBuffer::create(indices)); + drawCommands->addChild(vsg::DrawIndexed::create(6, 1, 0, 0, 0)); + + if (sharedObjects) + { + sharedObjects->share(drawCommands->children); + sharedObjects->share(drawCommands); + } + + // share the pipeline config and initialize it if it's unique + if (sharedObjects) + sharedObjects->share(graphicsPipelineConfig, [](auto gpc) { gpc->init(); }); + else + graphicsPipelineConfig->init(); + + // create StateGroup as the root of the scene/command graph to hold the GraphicsPipeline, and binding of Descriptors to decorate the whole graph + auto stateGroup = vsg::StateGroup::create(); + + graphicsPipelineConfig->copyTo(stateGroup, sharedObjects); + + stateGroup->addChild(drawCommands); + + return stateGroup; +} + +int main(int argc, char** argv) +{ + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + auto windowTraits = vsg::WindowTraits::create(arguments); + + auto options = vsg::Options::create(); + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + options->sharedObjects = vsg::SharedObjects::create(); + +#ifdef vsgXchange_all + // add vsgXchange's support for reading and writing 3rd party file formats + options->add(vsgXchange::all::create()); +#endif + + options->readOptions(arguments); + + auto outputFile = arguments.value("", "-o"); + + auto scenegraph = vsg::Group::create(); + vsg::vec3 position(0.0f, 0.0f, 0.0f); + vsg::vec2 delta(16.0f, 16.0f); + + for(auto i = 1; i < argc; ++i) + { + if (auto image = vsg::read_cast(arguments[i], options)) + { + vsg::vec2 extents(static_cast(image->width()), static_cast(image->height())); + + // default mipmap settings + { + auto sampler = vsg::Sampler::create(); + sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler->addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler->minLod = 0.0f; + sampler->maxLod = VK_LOD_CLAMP_NONE; + + if (auto model = createTexturedQuad(position, extents, image, sampler, options)) + { + scenegraph->addChild(model); + position.x += extents[0] + delta[0] * 2.0f; + } + } + + // create an image for each mipmap level. + if (auto mipmaps = image->computeMipmapOffsets(); mipmaps.size()>1) + { + for(size_t level = 0; level < mipmaps.size(); ++level) + { + auto sampler = vsg::Sampler::create(); + sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler->addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + sampler->minLod = static_cast(level); + sampler->maxLod = static_cast(level); + + if (auto model = createTexturedQuad(position, extents, image, sampler, options)) + { + scenegraph->addChild(model); + position.x += extents[0] + delta[0]; + } + } + } + + position.x = 0.0f; + position.z += extents[1] + delta[1]; + } + } + + if (scenegraph->children.empty()) + { + std::cout<<"No images loaded to render, please specify an image filename on command line."<addWindow(window); + + vsg::ComputeBounds computeBounds; + scenegraph->accept(computeBounds); + vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; + double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.6 * 3.0; + + std::cout << "centre = " << centre << std::endl; + std::cout << "radius = " << radius << std::endl; + + // camera related details + double nearFarRatio = 0.001; + auto viewport = vsg::ViewportState::create(0, 0, window->extent2D().width, window->extent2D().height); + auto perspective = vsg::Perspective::create(60.0, static_cast(window->extent2D().width) / static_cast(window->extent2D().height), nearFarRatio * radius, radius * 10.0); + auto lookAt = vsg::LookAt::create(centre + vsg::dvec3(0.0, -radius * 3.5, 0.0), centre, vsg::dvec3(0.0, 0.0, 1.0)); + auto camera = vsg::Camera::create(perspective, lookAt, viewport); + + auto commandGraph = vsg::createCommandGraphForView(window, camera, scenegraph); + viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + + // compile the Vulkan objects + viewer->compile(); + + if (outputFile) + { + vsg::write(scenegraph, outputFile, options); + return 0; + } + + // assign a CloseHandler to the Viewer to respond to pressing Escape or the window close button + viewer->addEventHandlers({vsg::CloseHandler::create(viewer)}); + + viewer->addEventHandler(vsg::Trackball::create(camera)); + + // main frame loop + while (viewer->advanceToNextFrame()) + { + viewer->handleEvents(); + + viewer->update(); + + viewer->recordAndSubmit(); + + viewer->present(); + } + + // clean up done automatically thanks to ref_ptr<> + return 0; +} From 5cf37a7c70a3ae2ff79c089ed4779768b4858986 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Oct 2025 14:50:30 +0000 Subject: [PATCH 02/15] Added text labels --- examples/state/vsgsampler/vsgsampler.cpp | 36 +++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 869502ea..5c94c321 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -78,6 +78,25 @@ vsg::ref_ptr createTexturedQuad(const vsg::vec3& position, const vsg: return stateGroup; } +vsg::ref_ptr createText(const vsg::vec3& position, const vsg::vec2& extents, const std::string& str, vsg::ref_ptr options) +{ + auto font = vsg::read_cast("fonts/times.vsgb", options); + + auto layout = vsg::StandardLayout::create(); + layout->glyphLayout = vsg::StandardLayout::LEFT_TO_RIGHT_LAYOUT; + layout->position = position; + layout->horizontal = vsg::vec3(extents.x, 0.0, 0.0); + layout->vertical = vsg::vec3(0.0, 0.0, extents.y); + layout->color = vsg::vec4(1.0, 1.0, 1.0, 1.0); + + auto text = vsg::Text::create(); + text->text = vsg::stringValue::create(str); + text->font = font; + text->layout = layout; + text->setup(0, options); + return text; +} + int main(int argc, char** argv) { // set up defaults and read command line arguments to override them @@ -101,11 +120,14 @@ int main(int argc, char** argv) auto scenegraph = vsg::Group::create(); vsg::vec3 position(0.0f, 0.0f, 0.0f); vsg::vec2 delta(16.0f, 16.0f); + vsg::vec2 textExtents(delta.x*0.5f, delta.y*0.5f); for(auto i = 1; i < argc; ++i) { - if (auto image = vsg::read_cast(arguments[i], options)) + std::string filename = arguments[i]; + if (auto image = vsg::read_cast(filename, options)) { + auto mipmapData = image->getObject("mipmapData"); vsg::vec2 extents(static_cast(image->width()), static_cast(image->height())); // default mipmap settings @@ -119,6 +141,8 @@ int main(int argc, char** argv) if (auto model = createTexturedQuad(position, extents, image, sampler, options)) { scenegraph->addChild(model); + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string(filename, "\n", image->width(), " x ", image->height()), options)); + position.x += extents[0] + delta[0] * 2.0f; } } @@ -136,7 +160,17 @@ int main(int argc, char** argv) if (auto model = createTexturedQuad(position, extents, image, sampler, options)) { + scenegraph->addChild(model); + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", level), options)); + + if (mipmapData) + { + auto& mipmapExtents = mipmapData->at(level); + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]*2.0f), textExtents, vsg::make_string(mipmapExtents), options)); + } + + position.x += extents[0] + delta[0]; } } From 5ab52715a2473bc8b67e3ab8838819e6051f2e7c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 31 Oct 2025 10:00:39 +0000 Subject: [PATCH 03/15] Added blockWidth/blockHeight to size of image. --- examples/state/vsgsampler/vsgsampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 5c94c321..71e4074c 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -128,7 +128,7 @@ int main(int argc, char** argv) if (auto image = vsg::read_cast(filename, options)) { auto mipmapData = image->getObject("mipmapData"); - vsg::vec2 extents(static_cast(image->width()), static_cast(image->height())); + vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); // default mipmap settings { From 003545d9a79dfff653abc1aba7adebf0a62b06e4 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 5 Nov 2025 17:33:59 +0000 Subject: [PATCH 04/15] Added checks for support image formats. --- examples/state/vsgsampler/vsgsampler.cpp | 94 +++++++++++++++++++----- 1 file changed, 77 insertions(+), 17 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 71e4074c..ce0a9ff8 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -117,19 +117,91 @@ int main(int argc, char** argv) auto outputFile = arguments.value("", "-o"); + // 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); + + auto instance = window->getOrCreateInstance(); + auto physicalDevice = window->getOrCreatePhysicalDevice(); + if (!physicalDevice) + { + std::cout<<"No vkPhyscialDevice available."<> images; + for(auto i = 1; i < argc; ++i) + { + vsg::Path filename = arguments[i]; + if (auto image = vsg::read_cast(filename, options)) images[filename] = image; + else std::cout<<"Unable to load "<(filename, options)) + VkImageType type = VK_IMAGE_TYPE_2D; + VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; + VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageCreateFlags flags = 0; + VkImageFormatProperties imageFormatProperties; + if (vkGetPhysicalDeviceImageFormatProperties(*physicalDevice, image->properties.format, type, tiling, usage, flags, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED) { - auto mipmapData = image->getObject("mipmapData"); - vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); + std::cout<getObject("mipmapData"); + vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); + + if (image->depth()==6) + { + std::cout<<"We have a cubemap, can't render for now."<addWindow(window); - vsg::ComputeBounds computeBounds; scenegraph->accept(computeBounds); vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; From 5ee97c3f20fa8406b796f8724214b29a1d14829f Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 6 Nov 2025 10:44:56 +0000 Subject: [PATCH 05/15] Added acceptance of RGB image formats that can be adapted by the VSG even when not supported directly by drivers --- examples/state/vsgsampler/vsgsampler.cpp | 33 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index ce0a9ff8..8ac90510 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -179,19 +179,38 @@ int main(int argc, char** argv) vsg::vec2 delta(16.0f, 16.0f); vsg::vec2 textExtents(delta.x*0.5f, delta.y*0.5f); + + auto formatSupported = [&](VkFormat format) -> bool + { + if (VK_FORMAT_R8G8B8_UNORM <= format && format <= VK_FORMAT_B8G8R8_SRGB) + { + // RGB formats are converted to RGBA automatically by the VSG when transferring images + return true; + } + else + { + VkImageType type = VK_IMAGE_TYPE_2D; + VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; + VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT; + VkImageCreateFlags flags = 0; + VkImageFormatProperties imageFormatProperties; + return vkGetPhysicalDeviceImageFormatProperties(*physicalDevice, format, type, tiling, usage, flags, &imageFormatProperties) != VK_ERROR_FORMAT_NOT_SUPPORTED; + } + }; + for(auto& [filename, image] : images) { - VkImageType type = VK_IMAGE_TYPE_2D; - VkImageTiling tiling = VK_IMAGE_TILING_OPTIMAL; - VkImageUsageFlags usage = VK_IMAGE_USAGE_SAMPLED_BIT; - VkImageCreateFlags flags = 0; - VkImageFormatProperties imageFormatProperties; - if (vkGetPhysicalDeviceImageFormatProperties(*physicalDevice, image->properties.format, type, tiling, usage, flags, &imageFormatProperties) == VK_ERROR_FORMAT_NOT_SUPPORTED) + if (!formatSupported(image->properties.format)) { - std::cout<properties.format && image->properties.format <= VK_FORMAT_B8G8R8_SRGB) + { + std::cout<<"RGB format in: "<getObject("mipmapData"); vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); From bd199054a9f449987619181eb6b5a8bc49da2ee8 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Thu, 6 Nov 2025 13:24:22 +0000 Subject: [PATCH 06/15] Cleaned up format information --- examples/state/vsgsampler/vsgsampler.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 8ac90510..7bdabe55 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -202,15 +202,10 @@ int main(int argc, char** argv) { if (!formatSupported(image->properties.format)) { - std::cout<properties.format<<" not supported by Vulkan driver/hardware."<properties.format && image->properties.format <= VK_FORMAT_B8G8R8_SRGB) - { - std::cout<<"RGB format in: "<getObject("mipmapData"); vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); From 06421cce876854d9b278fb52297695c734d60fdf Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Nov 2025 11:07:14 +0000 Subject: [PATCH 07/15] Added -f numFrames command line option. --- examples/state/vsgsampler/vsgsampler.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 7bdabe55..7c88a771 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -115,6 +115,7 @@ int main(int argc, char** argv) options->readOptions(arguments); + auto numFrames = arguments.value(-1, "-f"); auto outputFile = arguments.value("", "-o"); // create the viewer and assign window(s) to it @@ -306,7 +307,7 @@ int main(int argc, char** argv) viewer->addEventHandler(vsg::Trackball::create(camera)); // main frame loop - while (viewer->advanceToNextFrame()) + while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0)) { viewer->handleEvents(); From 537b961543c2bc8d8bc3a1851bfcf080260f0566 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 11 Nov 2025 12:28:39 +0000 Subject: [PATCH 08/15] Added --maxLod value command line parameters to set the default Sampler::maxLod --- examples/state/vsgsampler/vsgsampler.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 7c88a771..13b5ec72 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -115,6 +115,9 @@ int main(int argc, char** argv) options->readOptions(arguments); + float maxLodDefault = VK_LOD_CLAMP_NONE; + arguments.read("--maxLod", maxLodDefault); + auto numFrames = arguments.value(-1, "-f"); auto outputFile = arguments.value("", "-o"); @@ -223,7 +226,7 @@ int main(int argc, char** argv) sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler->addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; sampler->minLod = 0.0f; - sampler->maxLod = VK_LOD_CLAMP_NONE; + sampler->maxLod = maxLodDefault; if (auto model = createTexturedQuad(position, extents, image, sampler, options)) { @@ -279,9 +282,6 @@ int main(int argc, char** argv) vsg::dvec3 centre = (computeBounds.bounds.min + computeBounds.bounds.max) * 0.5; double radius = vsg::length(computeBounds.bounds.max - computeBounds.bounds.min) * 0.6 * 3.0; - std::cout << "centre = " << centre << std::endl; - std::cout << "radius = " << radius << std::endl; - // camera related details double nearFarRatio = 0.001; auto viewport = vsg::ViewportState::create(0, 0, window->extent2D().width, window->extent2D().height); From 8d3f867925518122779c6e6a561e78323d556529 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sat, 15 Nov 2025 11:26:58 +0000 Subject: [PATCH 09/15] Refinements to work changes to core VSG --- examples/state/vsgsampler/vsgsampler.cpp | 28 ++++++++++++++---------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 13b5ec72..b7c8e12d 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -118,6 +118,7 @@ int main(int argc, char** argv) float maxLodDefault = VK_LOD_CLAMP_NONE; arguments.read("--maxLod", maxLodDefault); + auto annotate = !arguments.read("--no-text"); auto numFrames = arguments.value(-1, "-f"); auto outputFile = arguments.value("", "-o"); @@ -214,9 +215,9 @@ int main(int argc, char** argv) vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); - if (image->depth()==6) + if (image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D) { - std::cout<<"We have a cubemap, can't render for now."<width()<<", "<height()<<", "<depth()<<"}"<addChild(model); - scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string(filename, "\n", image->width(), " x ", image->height()), options)); + if (annotate) + { + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string(filename, "\n", image->width(), " x ", image->height(), " format = ", image->properties.format), options)); + } position.x += extents[0] + delta[0] * 2.0f; } } // create an image for each mipmap level. - if (auto mipmaps = image->computeMipmapOffsets(); mipmaps.size()>1) + if (image->properties.maxNumMipmaps > 1) { - for(size_t level = 0; level < mipmaps.size(); ++level) + for(uint8_t level = 0; level < image->properties.maxNumMipmaps; ++level) { auto sampler = vsg::Sampler::create(); sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; @@ -252,14 +256,16 @@ int main(int argc, char** argv) { scenegraph->addChild(model); - scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", level), options)); - - if (mipmapData) + if (annotate) { - auto& mipmapExtents = mipmapData->at(level); - scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]*2.0f), textExtents, vsg::make_string(mipmapExtents), options)); - } + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", level), options)); + if (mipmapData) + { + auto& mipmapExtents = mipmapData->at(level); + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]*2.0f), textExtents, vsg::make_string(mipmapExtents), options)); + } + } position.x += extents[0] + delta[0]; } From 8f0bde540859b0f47eef8c41a7c44d1d50b7e779 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Sun, 16 Nov 2025 12:43:23 +0000 Subject: [PATCH 10/15] Renamed Properties.maxNumMipMaps to Properties.mipLevels to be consistent with Vulkan naming. --- examples/app/vsgskybox/vsgskybox.cpp | 2 +- examples/state/vsgsampler/vsgsampler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/app/vsgskybox/vsgskybox.cpp b/examples/app/vsgskybox/vsgskybox.cpp index f9e95607..d6b3739c 100644 --- a/examples/app/vsgskybox/vsgskybox.cpp +++ b/examples/app/vsgskybox/vsgskybox.cpp @@ -62,7 +62,7 @@ vsg::ref_ptr createSkybox(const vsg::Path& filename, vsg::ref_ptrmaxLod = data->properties.maxNumMipmaps; + sampler->maxLod = data->properties.mipLevels; auto texture = vsg::DescriptorImage::create(sampler, data, 0, 0, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER); diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index b7c8e12d..2c428413 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -215,7 +215,7 @@ int main(int argc, char** argv) vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); - if (image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D) + if (image->depth()>1 /*image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D*/) { std::cout<<"image "<width()<<", "<height()<<", "<depth()<<"}"<properties.maxNumMipmaps > 1) + if (image->properties.mipLevels > 1) { - for(uint8_t level = 0; level < image->properties.maxNumMipmaps; ++level) + for(uint8_t level = 0; level < image->properties.mipLevels; ++level) { auto sampler = vsg::Sampler::create(); sampler->addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; From 15b74b1ccc40c89d836fa2842631b07486bd7e8a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 18 Nov 2025 15:54:20 +0000 Subject: [PATCH 11/15] Remapped images with depth of 1 but not set to 2D to VK_IMAGE_VIEW_TYPE_2D --- examples/state/vsgsampler/vsgsampler.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 2c428413..1108494c 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -214,6 +214,10 @@ int main(int argc, char** argv) auto mipmapData = image->getObject("mipmapData"); vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); + if (image->depth() == 1 && image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D) + { + image->properties.imageViewType = VK_IMAGE_VIEW_TYPE_2D; + } if (image->depth()>1 /*image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D*/) { From 3d40f3b065b409108ddf537f065d91ba6439e944 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 18 Nov 2025 15:58:43 +0000 Subject: [PATCH 12/15] Updated to use latest vsg::Data/MipmapLayout API --- examples/state/vsgsampler/vsgsampler.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 1108494c..49a638f0 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -211,9 +211,6 @@ int main(int argc, char** argv) continue; } - auto mipmapData = image->getObject("mipmapData"); - vsg::vec2 extents(static_cast(image->width() * image->properties.blockWidth), static_cast(image->height() * image->properties.blockHeight)); - if (image->depth() == 1 && image->properties.imageViewType != VK_IMAGE_VIEW_TYPE_2D) { image->properties.imageViewType = VK_IMAGE_VIEW_TYPE_2D; @@ -225,6 +222,10 @@ int main(int argc, char** argv) } else { + auto mipmapLayout = image->getMipmapLayout(); + auto [width, height, depth] = image->pixelExtents(); + vsg::vec2 extents(width, height); + // default mipmap settings { auto sampler = vsg::Sampler::create(); @@ -264,9 +265,9 @@ int main(int argc, char** argv) { scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", level), options)); - if (mipmapData) + if (mipmapLayout) { - auto& mipmapExtents = mipmapData->at(level); + auto& mipmapExtents = mipmapLayout->at(level); scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]*2.0f), textExtents, vsg::make_string(mipmapExtents), options)); } } From 6d71ebdc56bae693fd5380009f39bb9bd72573ca Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 18 Nov 2025 16:01:19 +0000 Subject: [PATCH 13/15] Fixed mapping of level to string --- examples/state/vsgsampler/vsgsampler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/state/vsgsampler/vsgsampler.cpp b/examples/state/vsgsampler/vsgsampler.cpp index 49a638f0..d598d9ff 100644 --- a/examples/state/vsgsampler/vsgsampler.cpp +++ b/examples/state/vsgsampler/vsgsampler.cpp @@ -263,7 +263,7 @@ int main(int argc, char** argv) scenegraph->addChild(model); if (annotate) { - scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", level), options)); + scenegraph->addChild(createText(position - vsg::vec3(0.0f, 0.0f, textExtents[1]), textExtents, vsg::make_string("level = ", int(level)), options)); if (mipmapLayout) { From 8619d1648a35677acd90cc1e00504e1dc6da742d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 19 Nov 2025 09:13:21 +0000 Subject: [PATCH 14/15] Bumped versions --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 922c21fd..430f6255 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.7) project(vsgExamples - VERSION 1.1.9 + VERSION 1.1.10 DESCRIPTION "Set of example programs that test and illustrate how to use the VulkanSceneGraph" LANGUAGES CXX C ) @@ -21,13 +21,13 @@ if (VULKAN_SDK) set(ENV{VULKAN_SDK} ${VULKAN_SDK}) endif() -find_package(vsg 1.1.11) +find_package(vsg 1.1.13) vsg_setup_dir_vars() vsg_setup_build_vars() # find the optional vsgXchange that can be used for reading a range of image and 3d model formats and shader compilation -find_package(vsgXchange 1.1.7 QUIET) +find_package(vsgXchange 1.1.8 QUIET) # find the optional vsgImGui that can be used for GUI elements added into graphics windows. find_package(vsgImGui QUIET) From 48b118d5113a8397348b5d716502cd20e551bc05 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 19 Nov 2025 09:27:10 +0000 Subject: [PATCH 15/15] Fixed version --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 430f6255..ac385780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ if (VULKAN_SDK) set(ENV{VULKAN_SDK} ${VULKAN_SDK}) endif() -find_package(vsg 1.1.13) +find_package(vsg 1.1.12) vsg_setup_dir_vars() vsg_setup_build_vars()