From 0ca9e09b433cf11050e929a800410aa1edb529e7 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Mon, 27 Jan 2025 15:54:46 +0000 Subject: [PATCH 01/10] Added vsgcolorspace example to illustrate seleciton of color space and visual effects. --- examples/app/CMakeLists.txt | 1 + examples/app/vsgcolorspace/CMakeLists.txt | 14 + examples/app/vsgcolorspace/vsgcolorspace.cpp | 422 +++++++++++++++++++ 3 files changed, 437 insertions(+) create mode 100644 examples/app/vsgcolorspace/CMakeLists.txt create mode 100644 examples/app/vsgcolorspace/vsgcolorspace.cpp diff --git a/examples/app/CMakeLists.txt b/examples/app/CMakeLists.txt index fc10151f..1df0a79d 100644 --- a/examples/app/CMakeLists.txt +++ b/examples/app/CMakeLists.txt @@ -16,6 +16,7 @@ add_subdirectory(vsgwindows) add_subdirectory(vsgcameras) add_subdirectory(vsgvalidate) add_subdirectory(vsgaxes) +add_subdirectory(vsgcolorspace) if (vsgXchange_FOUND) add_subdirectory(vsghelloworld) diff --git a/examples/app/vsgcolorspace/CMakeLists.txt b/examples/app/vsgcolorspace/CMakeLists.txt new file mode 100644 index 00000000..0d1cf038 --- /dev/null +++ b/examples/app/vsgcolorspace/CMakeLists.txt @@ -0,0 +1,14 @@ +set(SOURCES + vsgcolorspace.cpp +) + +add_executable(vsgcolorspace ${SOURCES}) + +target_link_libraries(vsgcolorspace vsg::vsg) + +if (vsgXchange_FOUND) + target_compile_definitions(vsgcolorspace PRIVATE vsgXchange_FOUND) + target_link_libraries(vsgcolorspace vsgXchange::vsgXchange) +endif() + +install(TARGETS vsgcolorspace RUNTIME DESTINATION bin) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp new file mode 100644 index 00000000..63638c20 --- /dev/null +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -0,0 +1,422 @@ +#include + +#ifdef vsgXchange_FOUND +# include +#endif + +#include +#include +#include +#include + +vsg::ref_ptr createTextureQuad(vsg::ref_ptr sourceData, vsg::ref_ptr options) +{ + auto builder = vsg::Builder::create(); + builder->options = options; + + vsg::StateInfo state; + state.image = sourceData; + state.lighting = false; + + vsg::GeometryInfo geom; + geom.dy.set(0.0f, 0.0f, 1.0f); + geom.dz.set(0.0f, -1.0f, 0.0f); + + return builder->createQuad(geom, state); +} + +void enableGenerateDebugInfo(vsg::ref_ptr options) +{ + auto shaderHints = vsg::ShaderCompileSettings::create(); + shaderHints->generateDebugInfo = true; + + auto& text = options->shaderSets["text"] = vsg::createTextShaderSet(options); + text->defaultShaderHints = shaderHints; + + auto& flat = options->shaderSets["flat"] = vsg::createFlatShadedShaderSet(options); + flat->defaultShaderHints = shaderHints; + + auto& phong = options->shaderSets["phong"] = vsg::createPhongShaderSet(options); + phong->defaultShaderHints = shaderHints; + + auto& pbr = options->shaderSets["pbr"] = vsg::createPhysicsBasedRenderingShaderSet(options); + pbr->defaultShaderHints = shaderHints; +} + +int main(int argc, char** argv) +{ + try + { + // set up defaults and read command line arguments to override them + vsg::CommandLine arguments(&argc, argv); + + // if we want to redirect std::cout and std::cerr to the vsg::Logger call vsg::Logger::redirect_stdout() + if (arguments.read({"--redirect-std", "-r"})) vsg::Logger::instance()->redirect_std(); + + // set up vsg::Options to pass in filepaths, ReaderWriters and other IO related options to use when reading and writing files. + auto options = vsg::Options::create(); + options->sharedObjects = vsg::SharedObjects::create(); + options->fileCache = vsg::getEnv("VSG_FILE_CACHE"); + options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); + +#ifdef vsgXchange_all + // add vsgXchange's support for reading and writing 3rd party file formats + options->add(vsgXchange::all::create()); +#endif + + arguments.read(options); + + auto windowTraits = vsg::WindowTraits::create(); + windowTraits->windowTitle = "vsgcolorspace"; + windowTraits->debugLayer = arguments.read({"--debug", "-d"}); + windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); + windowTraits->synchronizationLayer = arguments.read("--sync"); + bool reportAverageFrameRate = arguments.read("--fps"); + if (arguments.read("--double-buffer")) windowTraits->swapchainPreferences.imageCount = 2; + if (arguments.read("--triple-buffer")) windowTraits->swapchainPreferences.imageCount = 3; // default + if (arguments.read("--IMMEDIATE")) { windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; } + if (arguments.read("--FIFO")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_FIFO_KHR; + if (arguments.read("--FIFO_RELAXED")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_FIFO_RELAXED_KHR; + if (arguments.read("--MAILBOX")) windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_MAILBOX_KHR; + if (arguments.read({"-t", "--test"})) + { + windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + windowTraits->fullscreen = true; + reportAverageFrameRate = true; + } + if (arguments.read({"--st", "--small-test"})) + { + windowTraits->swapchainPreferences.presentMode = VK_PRESENT_MODE_IMMEDIATE_KHR; + windowTraits->width = 192, windowTraits->height = 108; + windowTraits->decoration = false; + reportAverageFrameRate = true; + } + + bool multiThreading = arguments.read("--mt"); + if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true; + if (arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height)) { windowTraits->fullscreen = false; } + if (arguments.read({"--no-frame", "--nf"})) windowTraits->decoration = false; + if (arguments.read("--or")) windowTraits->overrideRedirect = true; + auto maxTime = arguments.value(std::numeric_limits::max(), "--max-time"); + + if (arguments.read("--d32")) windowTraits->depthFormat = VK_FORMAT_D32_SFLOAT; + if (arguments.read("--sRGB")) windowTraits->swapchainPreferences.surfaceFormat = {VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; + if (arguments.read("--RGB")) windowTraits->swapchainPreferences.surfaceFormat = {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; + + arguments.read("--screen", windowTraits->screenNum); + arguments.read("--display", windowTraits->display); + arguments.read("--samples", windowTraits->samples); + if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); + auto numFrames = arguments.value(-1, "-f"); + auto pathFilename = arguments.value("", "-p"); + auto loadLevels = arguments.value(0, "--load-levels"); + auto maxPagedLOD = arguments.value(0, "--maxPagedLOD"); + auto horizonMountainHeight = arguments.value(0.0, "--hmh"); + auto nearFarRatio = arguments.value(0.001, "--nfr"); + if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; + + bool depthClamp = arguments.read({"--dc", "--depthClamp"}); + if (depthClamp) + { + std::cout << "Enabled depth clamp." << std::endl; + auto deviceFeatures = windowTraits->deviceFeatures = vsg::DeviceFeatures::create(); + deviceFeatures->get().samplerAnisotropy = VK_TRUE; + deviceFeatures->get().depthClamp = VK_TRUE; + } + + vsg::ref_ptr resourceHints; + if (auto resourceHintsFilename = arguments.value("", "--rh")) + { + resourceHints = vsg::read_cast(resourceHintsFilename, options); + } + + if (auto outputResourceHintsFilename = arguments.value("", "--orh")) + { + if (!resourceHints) resourceHints = vsg::ResourceHints::create(); + vsg::write(resourceHints, outputResourceHintsFilename, options); + return 0; + } + + if (arguments.read({"--shader-debug-info", "--sdi"})) + { + enableGenerateDebugInfo(options); + windowTraits->deviceExtensionNames.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); + } + + if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); + auto logFilename = arguments.value("", "--log"); + + vsg::ref_ptr instrumentation; + if (arguments.read({"--gpu-annotation", "--ga"}) && vsg::isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) + { + windowTraits->debugUtils = true; + + auto gpu_instrumentation = vsg::GpuAnnotation::create(); + if (arguments.read("--name")) + gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_name; + else if (arguments.read("--className")) + gpu_instrumentation->labelType = vsg::GpuAnnotation::Object_className; + else if (arguments.read("--func")) + gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; + + instrumentation = gpu_instrumentation; + } + else if (arguments.read({"--profiler", "--pr"})) + { + // set Profiler options + auto settings = vsg::Profiler::Settings::create(); + arguments.read("--cpu", settings->cpu_instrumentation_level); + arguments.read("--gpu", settings->gpu_instrumentation_level); + arguments.read("--log-size", settings->log_size); + + // create the profiler + instrumentation = vsg::Profiler::create(settings); + } + + vsg::Affinity affinity; + uint32_t cpu = 0; + while (arguments.read("-c", cpu)) + { + affinity.cpus.insert(cpu); + } + + // should animations be automatically played + auto autoPlay = !arguments.read({"--no-auto-play", "--nop"}); + + if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); + + // create the basic window so can then get the various Vulkan related connections like vkSurface + vkPhysicalDevice + auto window = vsg::Window::create(windowTraits); + if (!window) + { + std::cout << "Could not create window." << std::endl; + return 1; + } + + auto physicalDevice = window->getOrCreatePhysicalDevice(); + auto surface = window->getOrCreateSurface(); + + std::cout<<"window->getInstance() "<getInstance()<getSurface() "<getSurface()<getPhysicalDevice() "<getPhysicalDevice()<vk(), surface->vk()); + for(auto& format : swapChainSupportDetails.formats) + { + std::cout<<" VkSurfaceFormatKHR{ VkFormat format = "<()) + { + group->addChild(node); + } + else if (auto data = object.cast()) + { + if (auto textureGeometry = createTextureQuad(data, options)) + { + group->addChild(textureGeometry); + } + } + else if (object) + { + std::cout << "Unable to view object of type " << object->className() << std::endl; + } + else + { + std::cout << "Unable to load file " << filename << std::endl; + } + } + + if (group->children.empty()) + { + return 1; + } + + vsg::ref_ptr vsg_scene; + if (group->children.size() == 1) + vsg_scene = group->children[0]; + else + vsg_scene = group; + + // create the viewer and assign window(s) to it + auto viewer = vsg::Viewer::create(); + + viewer->addWindow(window); + + // compute the bounds of the scene graph to help position camera + vsg::ComputeBounds computeBounds; + vsg_scene->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; + + // 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)); + + auto cameraAnimation = vsg::CameraAnimationHandler::create(camera, pathFilename, options); + viewer->addEventHandler(cameraAnimation); + if (autoPlay && cameraAnimation->animation) + { + cameraAnimation->play(); + if (reportAverageFrameRate) maxTime = cameraAnimation->animation->maxTime(); + } + + viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + + // if required preload specific number of PagedLOD levels. + if (loadLevels > 0) + { + vsg::LoadPagedLOD loadPagedLOD(camera, loadLevels); + + auto startTime = vsg::clock::now(); + + vsg_scene->accept(loadPagedLOD); + + auto time = std::chrono::duration(vsg::clock::now() - startTime).count(); + std::cout << "No. of tiles loaded " << loadPagedLOD.numTiles << " in " << time << "ms." << std::endl; + } + + auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); + viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + + if (instrumentation) viewer->assignInstrumentation(instrumentation); + + if (multiThreading) + { + viewer->setupThreading(); + + if (affinity) + { + auto cpu_itr = affinity.cpus.begin(); + + // set affinity of main thread + if (cpu_itr != affinity.cpus.end()) + { + std::cout << "vsg::setAffinity() " << *cpu_itr << std::endl; + vsg::setAffinity(vsg::Affinity(*cpu_itr++)); + } + + for (auto& thread : viewer->threads) + { + if (thread.joinable() && cpu_itr != affinity.cpus.end()) + { + std::cout << "vsg::setAffinity(" << thread.get_id() << ") " << *cpu_itr << std::endl; + vsg::setAffinity(thread, vsg::Affinity(*cpu_itr++)); + } + } + } + } + else if (affinity) + { + std::cout << "vsg::setAffinity("; + for (auto cpu_num : affinity.cpus) + { + std::cout << " " << cpu_num; + } + std::cout << " )" << std::endl; + + vsg::setAffinity(affinity); + } + + viewer->compile(resourceHints); + + if (maxPagedLOD > 0) + { + // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required. + for (auto& task : viewer->recordAndSubmitTasks) + { + if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD; + } + } + + if (autoPlay) + { + // find any animation groups in the loaded scene graph and play the first animation in each of the animation groups. + auto animationGroups = vsg::visit(vsg_scene).animationGroups; + for (auto ag : animationGroups) + { + if (!ag->animations.empty()) viewer->animationManager->play(ag->animations.front()); + } + } + + viewer->start_point() = vsg::clock::now(); + + // rendering main loop + while (viewer->advanceToNextFrame() && (numFrames < 0 || (numFrames--) > 0) && (viewer->getFrameStamp()->simulationTime < maxTime)) + { + // 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; + } + + if (auto profiler = instrumentation.cast()) + { + instrumentation->finish(); + if (logFilename) + { + std::ofstream fout(logFilename); + profiler->log->report(fout); + } + else + { + profiler->log->report(std::cout); + } + } + } + catch (const vsg::Exception& ve) + { + for (int i = 0; i < argc; ++i) std::cerr << argv[i] << " "; + std::cerr << "\n[Exception] - " << ve.message << " result = " << ve.result << std::endl; + return 1; + } + + // clean up done automatically thanks to ref_ptr<> + return 0; +} From 3c5b57d84106a42255833d0ec4c3c61e2ef66557 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 09:24:34 +0000 Subject: [PATCH 02/10] Simplified example --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 181 ++----------------- 1 file changed, 13 insertions(+), 168 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index 63638c20..7f17b63c 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -25,24 +25,6 @@ vsg::ref_ptr createTextureQuad(vsg::ref_ptr sourceData, vs return builder->createQuad(geom, state); } -void enableGenerateDebugInfo(vsg::ref_ptr options) -{ - auto shaderHints = vsg::ShaderCompileSettings::create(); - shaderHints->generateDebugInfo = true; - - auto& text = options->shaderSets["text"] = vsg::createTextShaderSet(options); - text->defaultShaderHints = shaderHints; - - auto& flat = options->shaderSets["flat"] = vsg::createFlatShadedShaderSet(options); - flat->defaultShaderHints = shaderHints; - - auto& phong = options->shaderSets["phong"] = vsg::createPhongShaderSet(options); - phong->defaultShaderHints = shaderHints; - - auto& pbr = options->shaderSets["pbr"] = vsg::createPhysicsBasedRenderingShaderSet(options); - pbr->defaultShaderHints = shaderHints; -} - int main(int argc, char** argv) { try @@ -92,7 +74,6 @@ int main(int argc, char** argv) reportAverageFrameRate = true; } - bool multiThreading = arguments.read("--mt"); if (arguments.read({"--fullscreen", "--fs"})) windowTraits->fullscreen = true; if (arguments.read({"--window", "-w"}, windowTraits->width, windowTraits->height)) { windowTraits->fullscreen = false; } if (arguments.read({"--no-frame", "--nf"})) windowTraits->decoration = false; @@ -110,7 +91,6 @@ int main(int argc, char** argv) auto numFrames = arguments.value(-1, "-f"); auto pathFilename = arguments.value("", "-p"); auto loadLevels = arguments.value(0, "--load-levels"); - auto maxPagedLOD = arguments.value(0, "--maxPagedLOD"); auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; @@ -124,62 +104,9 @@ int main(int argc, char** argv) deviceFeatures->get().depthClamp = VK_TRUE; } - vsg::ref_ptr resourceHints; - if (auto resourceHintsFilename = arguments.value("", "--rh")) - { - resourceHints = vsg::read_cast(resourceHintsFilename, options); - } - - if (auto outputResourceHintsFilename = arguments.value("", "--orh")) - { - if (!resourceHints) resourceHints = vsg::ResourceHints::create(); - vsg::write(resourceHints, outputResourceHintsFilename, options); - return 0; - } - - if (arguments.read({"--shader-debug-info", "--sdi"})) - { - enableGenerateDebugInfo(options); - windowTraits->deviceExtensionNames.push_back(VK_KHR_SHADER_NON_SEMANTIC_INFO_EXTENSION_NAME); - } - if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); auto logFilename = arguments.value("", "--log"); - vsg::ref_ptr instrumentation; - if (arguments.read({"--gpu-annotation", "--ga"}) && vsg::isExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME)) - { - windowTraits->debugUtils = true; - - auto gpu_instrumentation = vsg::GpuAnnotation::create(); - if (arguments.read("--name")) - gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_name; - else if (arguments.read("--className")) - gpu_instrumentation->labelType = vsg::GpuAnnotation::Object_className; - else if (arguments.read("--func")) - gpu_instrumentation->labelType = vsg::GpuAnnotation::SourceLocation_function; - - instrumentation = gpu_instrumentation; - } - else if (arguments.read({"--profiler", "--pr"})) - { - // set Profiler options - auto settings = vsg::Profiler::Settings::create(); - arguments.read("--cpu", settings->cpu_instrumentation_level); - arguments.read("--gpu", settings->gpu_instrumentation_level); - arguments.read("--log-size", settings->log_size); - - // create the profiler - instrumentation = vsg::Profiler::create(settings); - } - - vsg::Affinity affinity; - uint32_t cpu = 0; - while (arguments.read("-c", cpu)) - { - affinity.cpus.insert(cpu); - } - // should animations be automatically played auto autoPlay = !arguments.read({"--no-auto-play", "--nop"}); @@ -215,48 +142,28 @@ int main(int argc, char** argv) return 1; } - auto group = vsg::Group::create(); + vsg::Path filename = arguments[1]; + auto object = vsg::read(filename, options); - vsg::Path path; - - // read any vsg files - for (int i = 1; i < argc; ++i) + vsg::ref_ptr vsg_scene; + if (auto data = object.cast()) { - vsg::Path filename = arguments[i]; - path = vsg::filePath(filename); - - auto object = vsg::read(filename, options); - if (auto node = object.cast()) - { - group->addChild(node); - } - else if (auto data = object.cast()) - { - if (auto textureGeometry = createTextureQuad(data, options)) - { - group->addChild(textureGeometry); - } - } - else if (object) - { - std::cout << "Unable to view object of type " << object->className() << std::endl; - } - else + if (auto textureGeometry = createTextureQuad(data, options)) { - std::cout << "Unable to load file " << filename << std::endl; + vsg_scene = textureGeometry; } } + else + { + vsg_scene = object.cast(); + } - if (group->children.empty()) + if (!vsg_scene) { + std::cout<<"No model loaded, please specify a model to load on command line."< vsg_scene; - if (group->children.size() == 1) - vsg_scene = group->children[0]; - else - vsg_scene = group; // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); @@ -314,55 +221,7 @@ int main(int argc, char** argv) auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); - if (instrumentation) viewer->assignInstrumentation(instrumentation); - - if (multiThreading) - { - viewer->setupThreading(); - - if (affinity) - { - auto cpu_itr = affinity.cpus.begin(); - - // set affinity of main thread - if (cpu_itr != affinity.cpus.end()) - { - std::cout << "vsg::setAffinity() " << *cpu_itr << std::endl; - vsg::setAffinity(vsg::Affinity(*cpu_itr++)); - } - - for (auto& thread : viewer->threads) - { - if (thread.joinable() && cpu_itr != affinity.cpus.end()) - { - std::cout << "vsg::setAffinity(" << thread.get_id() << ") " << *cpu_itr << std::endl; - vsg::setAffinity(thread, vsg::Affinity(*cpu_itr++)); - } - } - } - } - else if (affinity) - { - std::cout << "vsg::setAffinity("; - for (auto cpu_num : affinity.cpus) - { - std::cout << " " << cpu_num; - } - std::cout << " )" << std::endl; - - vsg::setAffinity(affinity); - } - - viewer->compile(resourceHints); - - if (maxPagedLOD > 0) - { - // set targetMaxNumPagedLODWithHighResSubgraphs after Viewer::compile() as it will assign any DatabasePager if required. - for (auto& task : viewer->recordAndSubmitTasks) - { - if (task->databasePager) task->databasePager->targetMaxNumPagedLODWithHighResSubgraphs = maxPagedLOD; - } - } + viewer->compile(); if (autoPlay) { @@ -395,20 +254,6 @@ int main(int argc, char** argv) 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; } - - if (auto profiler = instrumentation.cast()) - { - instrumentation->finish(); - if (logFilename) - { - std::ofstream fout(logFilename); - profiler->log->report(fout); - } - else - { - profiler->log->report(std::cout); - } - } } catch (const vsg::Exception& ve) { From 6b40c2783983524e679cac9c6fc70243d3198285 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 11:30:27 +0000 Subject: [PATCH 03/10] Added creation of multiple windows with the various swapchain format specification. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 102 ++++++++++--------- 1 file changed, 54 insertions(+), 48 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index 7f17b63c..e89f456b 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -49,7 +49,6 @@ int main(int argc, char** argv) arguments.read(options); auto windowTraits = vsg::WindowTraits::create(); - windowTraits->windowTitle = "vsgcolorspace"; windowTraits->debugLayer = arguments.read({"--debug", "-d"}); windowTraits->apiDumpLayer = arguments.read({"--api", "-a"}); windowTraits->synchronizationLayer = arguments.read("--sync"); @@ -81,8 +80,8 @@ int main(int argc, char** argv) auto maxTime = arguments.value(std::numeric_limits::max(), "--max-time"); if (arguments.read("--d32")) windowTraits->depthFormat = VK_FORMAT_D32_SFLOAT; - if (arguments.read("--sRGB")) windowTraits->swapchainPreferences.surfaceFormat = {VK_FORMAT_B8G8R8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; - if (arguments.read("--RGB")) windowTraits->swapchainPreferences.surfaceFormat = {VK_FORMAT_B8G8R8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}; + + windowTraits->windowTitle = vsg::make_string("Default swapchain preferences VkSurfaceFormatKHR{ VkFormat format = ", windowTraits->swapchainPreferences.surfaceFormat.format, ", VkColorSpaceKHR colorSpace = ", windowTraits->swapchainPreferences.surfaceFormat.colorSpace,"}"); arguments.read("--screen", windowTraits->screenNum); arguments.read("--display", windowTraits->display); @@ -90,7 +89,6 @@ int main(int argc, char** argv) if (int log_level = 0; arguments.read("--log-level", log_level)) vsg::Logger::instance()->level = vsg::Logger::Level(log_level); auto numFrames = arguments.value(-1, "-f"); auto pathFilename = arguments.value("", "-p"); - auto loadLevels = arguments.value(0, "--load-levels"); auto horizonMountainHeight = arguments.value(0.0, "--hmh"); auto nearFarRatio = arguments.value(0.001, "--nfr"); if (arguments.read("--rgb")) options->mapRGBtoRGBAHint = false; @@ -113,19 +111,15 @@ int main(int argc, char** argv) if (arguments.errors()) return arguments.writeErrorMessages(std::cerr); // create the basic window so can then get the various Vulkan related connections like vkSurface + vkPhysicalDevice - auto window = vsg::Window::create(windowTraits); - if (!window) + auto initial_window = vsg::Window::create(windowTraits); + if (!initial_window) { std::cout << "Could not create window." << std::endl; return 1; } - auto physicalDevice = window->getOrCreatePhysicalDevice(); - auto surface = window->getOrCreateSurface(); - - std::cout<<"window->getInstance() "<getInstance()<getSurface() "<getSurface()<getPhysicalDevice() "<getPhysicalDevice()<getOrCreatePhysicalDevice(); + auto surface = initial_window->getOrCreateSurface(); // https://registry.khronos.org/vulkan/specs/latest/man/html/VkFormat.html // https://registry.khronos.org/vulkan/specs/latest/man/html/VkColorSpaceKHR.html @@ -142,6 +136,27 @@ int main(int argc, char** argv) return 1; } + + std::vector> windows; + + windows.push_back(initial_window); + + for(auto& format : swapChainSupportDetails.formats) + { + if (vsg::compare_memory(windowTraits->swapchainPreferences.surfaceFormat, format) != 0) + { + auto local_windowTraits = vsg::WindowTraits::create(); + local_windowTraits->windowTitle = vsg::make_string("Alternate swapchain preferences VkSurfaceFormatKHR{ VkFormat format = ", format.format, ", VkColorSpaceKHR colorSpace = ", format.colorSpace,"}"); + local_windowTraits->swapchainPreferences.surfaceFormat = format; + local_windowTraits->device = initial_window->getOrCreateDevice(); + + auto local_window = vsg::Window::create(local_windowTraits); + if (local_window) windows.push_back(local_window); + } + } + + std::cout<<"windows.size() = "<addWindow(window); + + vsg::CommandGraphs commandGraphs; // compute the bounds of the scene graph to help position camera vsg::ComputeBounds computeBounds; @@ -176,50 +192,40 @@ 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; - // 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) + // For each created window assign the each window assocaited views and trackball camera manipulator to the viewer + for(auto& window : windows) { - 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->addWindow(window); - auto cameraAnimation = vsg::CameraAnimationHandler::create(camera, pathFilename, options); - viewer->addEventHandler(cameraAnimation); - if (autoPlay && cameraAnimation->animation) - { - cameraAnimation->play(); - if (reportAverageFrameRate) maxTime = cameraAnimation->animation->maxTime(); - } + // 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)); - viewer->addEventHandler(vsg::Trackball::create(camera, ellipsoidModel)); + 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); + } - // if required preload specific number of PagedLOD levels. - if (loadLevels > 0) - { - vsg::LoadPagedLOD loadPagedLOD(camera, loadLevels); + auto camera = vsg::Camera::create(perspective, lookAt, vsg::ViewportState::create(window->extent2D())); - auto startTime = vsg::clock::now(); + auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); + commandGraphs.push_back(commandGraph); - vsg_scene->accept(loadPagedLOD); + auto trackball = vsg::Trackball::create(camera, ellipsoidModel); + trackball->addWindow(window); - auto time = std::chrono::duration(vsg::clock::now() - startTime).count(); - std::cout << "No. of tiles loaded " << loadPagedLOD.numTiles << " in " << time << "ms." << std::endl; + viewer->addEventHandler(trackball); } - auto commandGraph = vsg::createCommandGraphForView(window, camera, vsg_scene); - viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); + // add close handler to respond to the close window button and pressing escape + viewer->addEventHandler(vsg::CloseHandler::create(viewer)); + + viewer->assignRecordAndSubmitTaskAndPresentation(commandGraphs); viewer->compile(); From 7d03600e518a5e9c3600e16f9f189ac626d1306d Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 12:02:41 +0000 Subject: [PATCH 04/10] Simplified the titles --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index e89f456b..01ff0f90 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -81,7 +81,7 @@ int main(int argc, char** argv) if (arguments.read("--d32")) windowTraits->depthFormat = VK_FORMAT_D32_SFLOAT; - windowTraits->windowTitle = vsg::make_string("Default swapchain preferences VkSurfaceFormatKHR{ VkFormat format = ", windowTraits->swapchainPreferences.surfaceFormat.format, ", VkColorSpaceKHR colorSpace = ", windowTraits->swapchainPreferences.surfaceFormat.colorSpace,"}"); + windowTraits->windowTitle = vsg::make_string("Default swapchain VkSurfaceFormatKHR{ VkFormat format = ", windowTraits->swapchainPreferences.surfaceFormat.format, ", VkColorSpaceKHR colorSpace = ", windowTraits->swapchainPreferences.surfaceFormat.colorSpace,"}"); arguments.read("--screen", windowTraits->screenNum); arguments.read("--display", windowTraits->display); @@ -146,7 +146,7 @@ int main(int argc, char** argv) if (vsg::compare_memory(windowTraits->swapchainPreferences.surfaceFormat, format) != 0) { auto local_windowTraits = vsg::WindowTraits::create(); - local_windowTraits->windowTitle = vsg::make_string("Alternate swapchain preferences VkSurfaceFormatKHR{ VkFormat format = ", format.format, ", VkColorSpaceKHR colorSpace = ", format.colorSpace,"}"); + local_windowTraits->windowTitle = vsg::make_string("Alternate swapchain VkSurfaceFormatKHR{ VkFormat format = ", format.format, ", VkColorSpaceKHR colorSpace = ", format.colorSpace,"}"); local_windowTraits->swapchainPreferences.surfaceFormat = format; local_windowTraits->device = initial_window->getOrCreateDevice(); From 2ad2150771b8793e0e755284c2559a4488338512 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 12:25:40 +0000 Subject: [PATCH 05/10] Added sharing of the window size. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index 01ff0f90..94b077dd 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -147,6 +147,9 @@ int main(int argc, char** argv) { auto local_windowTraits = vsg::WindowTraits::create(); local_windowTraits->windowTitle = vsg::make_string("Alternate swapchain VkSurfaceFormatKHR{ VkFormat format = ", format.format, ", VkColorSpaceKHR colorSpace = ", format.colorSpace,"}"); + local_windowTraits->width = windowTraits->width; + local_windowTraits->height = windowTraits->height; + local_windowTraits->fullscreen = windowTraits->fullscreen; local_windowTraits->swapchainPreferences.surfaceFormat = format; local_windowTraits->device = initial_window->getOrCreateDevice(); From 2e90e1c5d4b719d03819287c416eccb581cdc9a2 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 13:17:49 +0000 Subject: [PATCH 06/10] Added positioning of windows --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index 94b077dd..5e89f9b6 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -141,18 +141,28 @@ int main(int argc, char** argv) windows.push_back(initial_window); + uint32_t i = 1; + uint32_t columns = static_cast(std::sqrt(static_cast(swapChainSupportDetails.formats.size())))+1; + uint32_t dx = windowTraits->width; + uint32_t dy = windowTraits->height; + for(auto& format : swapChainSupportDetails.formats) { if (vsg::compare_memory(windowTraits->swapchainPreferences.surfaceFormat, format) != 0) { auto local_windowTraits = vsg::WindowTraits::create(); local_windowTraits->windowTitle = vsg::make_string("Alternate swapchain VkSurfaceFormatKHR{ VkFormat format = ", format.format, ", VkColorSpaceKHR colorSpace = ", format.colorSpace,"}"); + local_windowTraits->x = dx * (i % columns); + local_windowTraits->y = dy * (i / columns); local_windowTraits->width = windowTraits->width; local_windowTraits->height = windowTraits->height; local_windowTraits->fullscreen = windowTraits->fullscreen; local_windowTraits->swapchainPreferences.surfaceFormat = format; + local_windowTraits->overrideRedirect = windowTraits->overrideRedirect; local_windowTraits->device = initial_window->getOrCreateDevice(); + ++i; + auto local_window = vsg::Window::create(local_windowTraits); if (local_window) windows.push_back(local_window); } From 54e0731bab68dbc9daf88325b5b2ff772f0f116c Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 13:58:45 +0000 Subject: [PATCH 07/10] Added spacing. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index 5e89f9b6..f958668a 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -143,8 +143,8 @@ int main(int argc, char** argv) uint32_t i = 1; uint32_t columns = static_cast(std::sqrt(static_cast(swapChainSupportDetails.formats.size())))+1; - uint32_t dx = windowTraits->width; - uint32_t dy = windowTraits->height; + uint32_t dx = windowTraits->width + 32; + uint32_t dy = windowTraits->height + 32; for(auto& format : swapChainSupportDetails.formats) { From c7e48c0cf5a4e3c87c72c3d424a63138c1ff947a Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 28 Jan 2025 18:46:01 +0000 Subject: [PATCH 08/10] Added placement of models loaded from the command line. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 89 ++++++++++++++------ 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index f958668a..cb46ee1b 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -25,6 +25,45 @@ vsg::ref_ptr createTextureQuad(vsg::ref_ptr sourceData, vs return builder->createQuad(geom, state); } +vsg::ref_ptr createLabelledSubgraph(const vsg::dvec3& position, const vsg::dvec3& dimensions, vsg::ref_ptr object, const std::string& label, vsg::ref_ptr options) +{ + vsg::ref_ptr subgraph; + if (auto data = object.cast()) subgraph = createTextureQuad(data, options); + else subgraph = object.cast(); + + if (!subgraph) return {}; + + // compute the bounds of the scene graph to help position camera + auto bounds = vsg::visit(subgraph).bounds; + + auto transform = vsg::MatrixTransform::create(); + transform->matrix = vsg::translate(position) * vsg::scale(vsg::length(dimensions) / vsg::length(bounds.max - bounds.min)) * vsg::translate(-(bounds.max.x+bounds.min.x)*0.5, -bounds.min.y, -bounds.min.z); + transform->addChild(subgraph); + + auto text = vsg::Text::create(); + + vsg::Path font_filename("fonts/times.vsgb"); + text->font = vsg::read_cast(font_filename, options); + + auto layout = vsg::StandardLayout::create(); + layout->position = position; + layout->horizontal = vsg::vec3(1.0, 0.0, 0.0); + layout->vertical = vsg::vec3(0.0, 0.0, 1.0); + layout->color = vsg::vec4(1.0, 1.0, 1.0, 1.0); + layout->horizontalAlignment = vsg::StandardLayout::CENTER_ALIGNMENT; + text->layout = layout; + + text->text = vsg::stringValue::create(label); + text->setup(0, options); + + auto group = vsg::Group::create(); + group->addChild(transform); + group->addChild(text); + + return group; +} + + int main(int argc, char** argv) { try @@ -130,13 +169,6 @@ int main(int argc, char** argv) std::cout<<" VkSurfaceFormatKHR{ VkFormat format = "<> windows; windows.push_back(initial_window); @@ -170,40 +202,41 @@ int main(int argc, char** argv) std::cout<<"windows.size() = "< vsg_scene; - if (auto data = object.cast()) + vsg::dvec3 position(0.0, 0.0, 0.0); + vsg::dvec3 dimensions(20.0, 20.0, 20.0); + + for (int ai = 1; ai < argc; ++ai) { - if (auto textureGeometry = createTextureQuad(data, options)) + vsg::Path filename = arguments[ai]; + auto object = vsg::read(filename, options); + std::cout<<"loaded "<(); - } + std::cout<<" added "<addChild(subgraph); - if (!vsg_scene) - { - std::cout<<"No model loaded, please specify a model to load on command line."<className() << std::endl; + } } // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); - vsg::CommandGraphs commandGraphs; // compute the bounds of the scene graph to help position camera - vsg::ComputeBounds computeBounds; - vsg_scene->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; + 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.5; + + std::cout<<"center = "< Date: Wed, 29 Jan 2025 13:38:52 +0000 Subject: [PATCH 09/10] Added rendering of different colours spheres and textured quads to illustrate sRGB and linear. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 107 ++++++++++++++++--- 1 file changed, 94 insertions(+), 13 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index cb46ee1b..d338e56f 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -25,6 +25,7 @@ vsg::ref_ptr createTextureQuad(vsg::ref_ptr sourceData, vs return builder->createQuad(geom, state); } + vsg::ref_ptr createLabelledSubgraph(const vsg::dvec3& position, const vsg::dvec3& dimensions, vsg::ref_ptr object, const std::string& label, vsg::ref_ptr options) { vsg::ref_ptr subgraph; @@ -202,29 +203,109 @@ int main(int argc, char** argv) std::cout<<"windows.size() = "<, std::string>; + using Row = std::vector; + std::vector rows; + + auto builder = vsg::Builder::create(); + builder->options = options; + + vsg::GeometryInfo geomInfo; + geomInfo.dx.set(1.0f, 0.0f, 0.0f); + geomInfo.dy.set(0.0f, 1.0f, 0.0f); + geomInfo.dz.set(0.0f, 0.0f, 1.0f); + + vsg::StateInfo stateInfo; + + auto createSphere= [&](float intensity) -> vsg::ref_ptr + { + geomInfo.color.set(intensity, intensity, intensity, 1.0f); + return builder->createSphere(geomInfo, stateInfo); + }; + + { + Row row; + row.push_back(ObjectLabel(createSphere(0.0f), vsg::make_string("linear(0.0f)"))); + row.push_back(ObjectLabel(createSphere(0.125f), vsg::make_string("linear(0.125f)"))); + row.push_back(ObjectLabel(createSphere(0.25f), vsg::make_string("linear(0.25f)"))); + row.push_back(ObjectLabel(createSphere(0.5f), vsg::make_string("linear(0.5f)"))); + row.push_back(ObjectLabel(createSphere(1.0f), vsg::make_string("linear(1.0f)"))); + rows.push_back(row); + } + + { + Row row; + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.0f)), vsg::make_string("sRGB_to_linear(0.0f)"))); + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.125f)), vsg::make_string("sRGB_to_linear(0.125f)"))); + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.25f)), vsg::make_string("sRGB_to_linear(0.25f)"))); + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.5f)), vsg::make_string("sRGB_to_linear(0.5f)"))); + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(1.0f)), vsg::make_string("sRGB_to_linear(1.0f)"))); + rows.push_back(row); + } + + { + Row row; + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.0f)), vsg::make_string("linear_to_sRGB(0.0f)"))); + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.125f)), vsg::make_string("linear_to_sRGB(0.125f)"))); + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.25f)), vsg::make_string("linear_to_sRGB(0.25f)"))); + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.5f)), vsg::make_string("linear_to_sRGB(0.5f)"))); + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(1.0f)), vsg::make_string("linear_to_sRGB(1.0f)"))); + rows.push_back(row); + } - vsg::dvec3 position(0.0, 0.0, 0.0); - vsg::dvec3 dimensions(20.0, 20.0, 20.0); - for (int ai = 1; ai < argc; ++ai) { - vsg::Path filename = arguments[ai]; - auto object = vsg::read(filename, options); - std::cout<<"loaded "<("textures/lz.vsgb", options); + if (image) { - std::cout<<" added "<addChild(subgraph); + //auto image_RGB = image->clone()->cast(); + auto image_uNorm = vsg::clone(image); + image_uNorm->properties.format = vsg::sRGB_to_uNorm(image->properties.format); + + auto image_sRGB = vsg::clone(image); + image_sRGB->properties.format = vsg::uNorm_to_sRGB(image->properties.format); - position.x += dimensions.x; + Row row; + row.push_back(ObjectLabel(createTextureQuad(image, options), vsg::make_string("image default loaded format: ", image->properties.format))); + row.push_back(ObjectLabel(createTextureQuad(image_uNorm, options), vsg::make_string("image treated as linear after vsg::sRGB_to_uNorm(..): ", image_uNorm->properties.format))); + row.push_back(ObjectLabel(createTextureQuad(image_sRGB, options), vsg::make_string("image treated as sRGB after vsg::uNorm_to_sRGB(..): ", image_sRGB->properties.format))); + + rows.push_back(row); } - else + } + + // create a row for loaded models + { + Row row; + for (int ai = 1; ai < argc; ++ai) { - std::cout << "Unable to view object of type " << object->className() << std::endl; + vsg::Path filename = arguments[ai]; + if (auto object = vsg::read(filename, options)) + { + row.push_back(ObjectLabel(object, vsg::make_string("model: ", filename))); + } } + if (!row.empty()) rows.push_back(row); } + auto vsg_scene = vsg::Group::create(); + + vsg::dvec3 position(0.0, 0.0, 0.0); + vsg::dvec3 dimensions(20.0, 20.0, 20.0); + vsg::dvec3 spacing = dimensions * 1.3; + + for(size_t r = 0; r< rows.size(); ++r) + { + Row& row = rows[r]; + for(size_t c = 0; c < row.size(); ++c) + { + auto& entry = row[c]; + position.x = spacing.x * static_cast(c); + position.z = spacing.z * static_cast(r); + if (auto subgraph = createLabelledSubgraph(position, dimensions, entry.first, entry.second, options)) vsg_scene->addChild(subgraph); + } + } // create the viewer and assign window(s) to it auto viewer = vsg::Viewer::create(); From 9d4a9206f7b8791d6d1e2afabd63edb5abab5a36 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 29 Jan 2025 14:27:13 +0000 Subject: [PATCH 10/10] Changed the sphere intensity to be a regular spacing. --- examples/app/vsgcolorspace/vsgcolorspace.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/app/vsgcolorspace/vsgcolorspace.cpp b/examples/app/vsgcolorspace/vsgcolorspace.cpp index d338e56f..bb252a1e 100644 --- a/examples/app/vsgcolorspace/vsgcolorspace.cpp +++ b/examples/app/vsgcolorspace/vsgcolorspace.cpp @@ -226,9 +226,9 @@ int main(int argc, char** argv) { Row row; row.push_back(ObjectLabel(createSphere(0.0f), vsg::make_string("linear(0.0f)"))); - row.push_back(ObjectLabel(createSphere(0.125f), vsg::make_string("linear(0.125f)"))); row.push_back(ObjectLabel(createSphere(0.25f), vsg::make_string("linear(0.25f)"))); row.push_back(ObjectLabel(createSphere(0.5f), vsg::make_string("linear(0.5f)"))); + row.push_back(ObjectLabel(createSphere(0.75f), vsg::make_string("linear(0.75f)"))); row.push_back(ObjectLabel(createSphere(1.0f), vsg::make_string("linear(1.0f)"))); rows.push_back(row); } @@ -236,9 +236,9 @@ int main(int argc, char** argv) { Row row; row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.0f)), vsg::make_string("sRGB_to_linear(0.0f)"))); - row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.125f)), vsg::make_string("sRGB_to_linear(0.125f)"))); row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.25f)), vsg::make_string("sRGB_to_linear(0.25f)"))); row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.5f)), vsg::make_string("sRGB_to_linear(0.5f)"))); + row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(0.75f)), vsg::make_string("sRGB_to_linear(0.75f)"))); row.push_back(ObjectLabel(createSphere(vsg::sRGB_to_linear_component(1.0f)), vsg::make_string("sRGB_to_linear(1.0f)"))); rows.push_back(row); } @@ -246,9 +246,9 @@ int main(int argc, char** argv) { Row row; row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.0f)), vsg::make_string("linear_to_sRGB(0.0f)"))); - row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.125f)), vsg::make_string("linear_to_sRGB(0.125f)"))); row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.25f)), vsg::make_string("linear_to_sRGB(0.25f)"))); row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.5f)), vsg::make_string("linear_to_sRGB(0.5f)"))); + row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(0.75f)), vsg::make_string("linear_to_sRGB(0.75f)"))); row.push_back(ObjectLabel(createSphere(vsg::linear_to_sRGB_component(1.0f)), vsg::make_string("linear_to_sRGB(1.0f)"))); rows.push_back(row); }