diff --git a/1_SettingTheScene/01_hello_world/hello_world.cpp b/1_SettingTheScene/01_hello_world/hello_world.cpp index 1d952eb..805e88b 100644 --- a/1_SettingTheScene/01_hello_world/hello_world.cpp +++ b/1_SettingTheScene/01_hello_world/hello_world.cpp @@ -37,14 +37,14 @@ int main(int, char**) // add close handler to respond to pressing the window close window button and pressing escape viewer->addEventHandler(vsg::CloseHandler::create(viewer)); - // add a trackball event handler to control the camera view use the mouse + // add a trackball event handler to control the camera view using the mouse viewer->addEventHandler(vsg::Trackball::create(camera)); // create a command graph to render the scene on specified window auto commandGraph = vsg::createCommandGraphForView(window, camera, scene); viewer->assignRecordAndSubmitTaskAndPresentation({commandGraph}); - // compile all the the Vulkan objects and transfer data required to render the scene + // compile all the Vulkan objects and transfer data required to render the scene viewer->compile(); // @@ -61,7 +61,7 @@ int main(int, char**) // record the commands in the scene graph and submit the completed command buffers to the vulkan queue viewer->recordAndSubmit(); - // wait for completion of the rendering and present the result color buffer to the Windows swap chain. + // wait for completion of the rendering and present the resulting color buffer to the Window's swap chain. viewer->present(); } diff --git a/1_SettingTheScene/BuildingVulkanSceneGraph.md b/1_SettingTheScene/BuildingVulkanSceneGraph.md index b742599..fb4e836 100644 --- a/1_SettingTheScene/BuildingVulkanSceneGraph.md +++ b/1_SettingTheScene/BuildingVulkanSceneGraph.md @@ -4,11 +4,11 @@ title: Building VulkanSceneGraph software permalink: /SettingTheScene/BuildingVulkanSceneGraph --- -To conclude this chapter we'll look at building the VulkanSceneGraph projects and a minimal standalone **hello world** application. +To conclude this chapter, we'll look at building the VulkanSceneGraph projects and a minimal standalone **hello world** application. -All VulkanSceneGraph projects, including the vsgTutorial exercises, are written in C++17 and using CMake as the cross-platform build system. To aid integration of the VulkanSceneGraph projects with other software, CMake config files are installed along with headers and libraries. CMake config files provide details of the libraries, header locations and any compiler definitions that are required when building software that use VulkanSceneGraph libraries and help to avoid issues when working across different platforms and with differences in static and dynamic library builds. +All VulkanSceneGraph projects, including the vsgTutorial exercises, are written in C++17 and use CMake as the cross-platform build system. To aid integration of the VulkanSceneGraph projects with other software, CMake config files are installed along with headers and libraries. CMake config files provide details of the libraries, header locations and any compiler definitions that are required when building software that uses VulkanSceneGraph libraries and help to avoid issues when working across different platforms and with differences in static and dynamic library builds. -The first task is to check out the main repositories and vsgTutorial for its exercises, for brevity we'll assume you have a Debian-based system and install headers, libraries and cmake files locally and set env paths up to find the install locations, this way there is no need to install to system directories. If you have other types of system use one of the alternative build instructions: +The first task is to check out the main repositories and vsgTutorial for its exercises, for brevity we'll assume you have a Debian-based system and install headers, libraries and CMake files locally and set env paths up to find the install locations, this way there is no need to install to system directories. If you have other types of systems, use one of the alternative build instructions: * Windows - to be written (looking for volunteers to write this.) * macOS - to be written (looking for volunteers to write this.) @@ -19,18 +19,18 @@ First we'll set up some environment variable, for ease of use you may wish to pu export INSTALL_DIR=~/Install export PROJECT_DIR=~/Projects export PATH=${PATH}:${INSTALL_DIR}/bin -export LD_LIBRARY_PATH=${D_LIBRARY_PATH}:${INSTALL_DIR}/lib +export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${INSTALL_DIR}/lib # env vars that are used to find example data, and locating where to cache files downloaded from HTTP during database paging export VSG_FILE_PATH=${PROJECT_DIR}/vsgExamples/data export VSG_FILE_CACHE=${PROJECT_DIR}/vsgFileCache -# only required if you use VulkanSDK rather than installing vulkan from distro repositories +# only required if you use VulkanSDK rather than installing Vulkan from distro repositories export VULKAN_SDK=${INSTALL_DIR}/VulkanSDK export PATH=${PATH}:${VULKAN_SDK}/bin ~~~ -Next install dependencies, under debian these are: +Next install dependencies, under Debian these are: ~~~ sh # dependencies useful for building the VulkanSceneGraph @@ -44,7 +44,7 @@ sudo apt-get install libvulkan-dev vulkan-tools vulkan-validationlayers sudo apt-get install libassimp-dev libfreetype-dev libopenexr-dev ~~~ -If you want to use the VulkanSDK instead of distro vulkan package you download it from [LunarG](https://vulkan.lunarg.com/sdk/home): +If you want to use the VulkanSDK instead of the distro vulkan package, download it from [LunarG](https://vulkan.lunarg.com/sdk/home): ~~~ sh wget https://sdk.lunarg.com/sdk/download/1.3.239.0/linux/vulkansdk-linux-x86_64-1.3.239.0.tar.gz @@ -87,7 +87,7 @@ To test out examples: ~~~ sh vsgdraw vsgviewer models/lz.vsgt -vsgdynamictextures +vsgdynamictexture ~~~ --- diff --git a/1_SettingTheScene/DevelopmentPrinciples.md b/1_SettingTheScene/DevelopmentPrinciples.md index f300910..cb78cfb 100644 --- a/1_SettingTheScene/DevelopmentPrinciples.md +++ b/1_SettingTheScene/DevelopmentPrinciples.md @@ -4,9 +4,9 @@ title: Development Principles permalink: /SettingTheScene/DevelopmentPrinciples --- -The VulkanSceneGraph Project goal is to make the development of high performance graphics and compute application quick and easy. Vulkan provides an excellent base for achieving high performance but is low-level and complicated to use. Simply wrapping a C API in C++ is not sufficient for application developers needs, a collection of high-level features that make development easy is what is required. The ***Vulkan Made Easy*** tag line was adopted for the vsg-dev github account as a daily reminder of our the projects fundamental goal. +The VulkanSceneGraph Project goal is to make the development of high-performance graphics and compute applications quick and easy. Vulkan provides an excellent base for achieving high performance but is low-level and complicated to use. Simply wrapping a C API in C++ is not sufficient for application developers' needs, a collection of high-level features that make development easy is what is required. The ***Vulkan Made Easy*** tag line was adopted for the vsg-dev GitHub account as a daily reminder of our project's fundamental goal. -The VulkanSceneGraph library is built upon the Scene Graph concept and is written specifically for Vulkan. Just as Vulkan is the successor to OpenGL, one that has wholly different API and architecture but retains the fundamental goal of providing a low-level, open, cross platform hardware abstraction, the VulkanSceneGarph is successor to the OpenSceneGraph, it also has an entirely different API and architecture but retains the fundamental goal of providing an open, cross patform high performance API for application developers. +The VulkanSceneGraph library is built upon the Scene Graph concept and is written specifically for Vulkan. Just as Vulkan is the successor to OpenGL, one that has wholly different API and architecture but retains the fundamental goal of providing a low-level, open, cross platform hardware abstraction, the VulkanSceneGraph is successor to the OpenSceneGraph, it also has an entirely different API and architecture but retains the fundamental goal of providing an open, cross platform high-performance API for application developers. ## Productivity and Performance @@ -14,18 +14,20 @@ The underlying principles that guided the VulkanSceneGraph development are the d The process of refining the software to better meet the needs of application developers won't stop with the VulkanSceneGraph-1.0 release, as the software develops these guiding principles will remain and we'll keep striving to deliver on the mantra Vulkan Made Easy. -As open source middle-ware used by developers we aspire for the software to be not just useful for the functionality it provides, but also as an example of good software, illustrating how to write modern C++ software and avoid the many pitfalls of writing advanced software. +As open-source middleware used by developers we aspire for the software to be not just useful for the functionality it provides, but also as an example of good software, illustrating how to write modern C++ software and avoid the many pitfalls of writing advanced software. ## Approach to Development -The VulkanSceneGraph is an open source project in license and practice: +The VulkanSceneGraph is an open-source project in license and practice: * From day 1 all work has been published on github and made available to all under the [MIT](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/LICENSE.md) license. -* Fully embrace the capabilities of C++ 17, modern CMAke and Github for building software, managing software and communicating. +* Fully embrace the capabilities of C++ 17, modern CMake and GitHub for building software, managing software and communicating. * Take lessons from developing the OpenSceneGraph, elements that are strong are updated and brought into the new scene graph, while flaws are recognized and used as a driver for finding better solutions. -* To bring in lessons from the wider C++ community the [C++CoreGuidlines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) are used to guide class design and implementation. +* To bring in lessons from the wider C++ community the [C++CoreGuidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) are used to guide class design and implementation. * Spiral Development Model: -Work follows a cycle starting at the centre and the moving around and outward following a spiral. On the innermost cycles of the spiral work is relatively simple and exploratory, but builds basic elements that later work can build upon, or on the next cycle round the sprial be revisted and refactored and made more capable if the original implementation is found insufficient. Steadily, understanding of the problem domain is built and the software is incrementally built out in features and robustness. -* While not formally an [Agile Software Development](https://en.wikipedia.org/wiki/Agile_software_development) project we draws upon it's manifesto: + +Work follows a cycle starting at the centre and then moving around and outward following a spiral. On the innermost cycles of the spiral, work is relatively simple and exploratory but builds basic elements that later work can build upon, or on the next cycle round the spiral can be revisited, refactored and made more capable if the original implementation is found insufficient. Steadily, understanding of the problem domain is built and the software is incrementally built out in features and robustness. + +* While not formally an [Agile Software Development](https://en.wikipedia.org/wiki/Agile_software_development) project we draw upon its manifesto: * **Individuals and interactions** over processes and tools * **Working software** over comprehensive documentation * **Customer collaboration** over contract negotiation @@ -33,21 +35,21 @@ Work follows a cycle starting at the centre and the moving around and outward fo ## Only high value dependencies -The VulkanSceneGraph library only has C++17, CMake and Vulkan as external dependencies. The Vulkan C headers are used rather then the Vulkan C++ header which is unnecessary as the Vulkan scene graph provides its own encapsulation of Vulkan objects in a way that is coherent with how they are used in the scene graph. +The VulkanSceneGraph library only has C++17, CMake and Vulkan as external dependencies. The Vulkan C headers are used rather than the Vulkan C++ header which is unnecessary as the VulkanSceneGraph provides its own encapsulation of Vulkan objects in a way that is coherent with how they are used in the scene graph. -For runtime shader compilation support the VulkanSceneGraph library uses the [glslang](https://github.com/KhronosGroup/glslang) library. Originally integrated as an optional external dependency, it is now built internally as a submodule. While gslang support is compiled in by default it can be toggled off by setting the CMake VSG_SUPPORTS_ShaderCompiler variable to 0 before building the source. Compiling glslang within the VulkanSceneGraph library resolved problems with inconsistent 3rd party packaging of glslang, so now users can have seamless experience across platforms. +For runtime shader compilation support the VulkanSceneGraph library uses the [glslang](https://github.com/KhronosGroup/glslang) library. Originally integrated as an optional external dependency, it is now built internally as a submodule. While glslang support is compiled in by default it can be toggled off by setting the CMake VSG_SUPPORTS_ShaderCompiler variable to 0 before building the source. Compiling glslang within the VulkanSceneGraph library resolved problems with inconsistent 3rd party packaging of glslang, so now users can have a seamless experience across platforms. -During the initial development of VulkanSceneGraph various other 3rd party dependencies, like gm and glfw, were considered for features like maths and windowing, but in each of these cases it was decided to implement the required features within the project rather than add an external dependency. The reasons for implementing the functionality within the project: +During the initial development of VulkanSceneGraph various other 3rd party dependencies, like glm and glfw, were considered for features like maths and windowing, but in each of these cases it was decided to implement the required features within the project rather than add an external dependency. The reasons for implementing the functionality within the project were: * Coherent class interfaces and naming * Coherent memory management * Provide classes focused just on the needs of the VulkanSceneGraph users -* Avoid the glue code required to bring different libraries to work well together +* Avoid the glue code required to make different libraries work well together * Keep memory and CPU overhead to a minimum * Keep dependencies to a minimum to avoid ***Dependency Hell*** * Keep licensing simple and permissive -An example how local implementations can achieve what we need with far less code can be seen looking at the glm maths library. It's a header only library with over 63,000 lines of code. The VulkanSceneGraph has all GLSL style vector, quaternion and matrix functionality it needs in less than 3,000 lines of code. The VulkanSceneGraph code base has 57,000 lines of code for its headers and source, and it has a scene graph, Vulkan integration, cross plarform windowing, viewer classes, serialization support and much more. +An example of how local implementations can achieve what we need with far less code can be seen looking at the glm library. It's a header only library with over 63,000 lines of code. The VulkanSceneGraph has all GLSL style vector, quaternion, and matrix functionality it needs in less than 3,000 lines of code. The VulkanSceneGraph code base has 57,000 lines of code for its headers and source, and it has a scene graph, Vulkan integration, cross platform windowing, viewer classes, serialization support and much more. --- diff --git a/1_SettingTheScene/Ecosystem.md b/1_SettingTheScene/Ecosystem.md index 603c706..f281a47 100644 --- a/1_SettingTheScene/Ecosystem.md +++ b/1_SettingTheScene/Ecosystem.md @@ -4,38 +4,39 @@ title: VulkanSceneGraph Ecosystem permalink: /SettingTheScene/Ecosystem --- -One of the weaknesses of the OpenSceneGraph project is that, while it started as small scene graph library, step by step it encompassed a wider range of features and dependencies. While the OpenSceneGraph stops short of providing all the functionality of a Game Engine it is bloated for the needs of many application developers. Early in the VulkanSceneGraph project the decision was made to create an ecosystem built on a general purpose scene graph library and a collection of companion libraries each focused on specific features that users can easily compile and use in their applications if they need them. +One of the weaknesses of the OpenSceneGraph project is that, while it started as a small scene graph library, step by step it encompassed a wider range of features and dependencies. While the OpenSceneGraph stops short of providing all the functionality of a Game Engine it is bloated for the needs of many application developers. Early in the VulkanSceneGraph project the decision was made to create an ecosystem built on a general purpose scene graph library and a collection of companion libraries each focused on specific features that users can easily compile and use in their applications if they need them. ## Foundation for all VulkanSceneGraph applications -Features that all applications developers using Vulkan will need, so provided by the VulkanSceneGraph library: +Features that all application developers using Vulkan will need, so provided by the VulkanSceneGraph library: * robustly create and cleanup data * serialization of scene graph objects to native ascii and binary file formats * extensible mechanism for reading/writing 3rd party data. * vector math classes and associated functions -* robust management of the lifetime Vulkan objects including support for Vulkan extensions +* robust management of the lifetime of Vulkan objects including support for Vulkan extensions * scene graph internal nodes, state and geometry * creation and management of Vulkan capable windows, offscreen buffers and event handling * support for views, cameras and control of them * support for commonly used graphics pipelines - flat shaded, phong and physics based rendering -## Ecosystem centered around vsg-dev github account +## Ecosystem centred around vsg-dev GitHub account -The [vsg-dev](https://github.com/vsg-dev) github account hosts the following projects which are officially supported as part the VulkanSceneGraph project, the three main projects that majority of developers will need to use are: -* [VulkanSceneGraph](https://github.com/vsg-dev/VulkanSceneGraph) - The VulkanSceneGraph library itself is capable of being used on it's own for standalone graphics applications, and for embedded platforms this may be the desired approach as it will minimize the code base that needs to be QA'd for sercurity and robustness, and minimizes the final executable size. -* [vsgXchange](https://github.com/vsg-dev/vsgXchange) -It is expected for most desktop applications users will also want to load a range of 2D image and 3D model data, to support this usage the library adds support for a wide range of image and 3d model formats, using assimp, as well as support for reading data from http/https using libcurl, and reading/writing/processing of GIS imagery and DEMS through the optional GDAL integration. -* [vsgExamples](https://github.com/vsg-dev/vsgExamples) +The [vsg-dev](https://github.com/vsg-dev) GitHub account hosts the following projects which are officially supported as part the VulkanSceneGraph project, the three main projects that the majority of developers will need to use are: +* [VulkanSceneGraph](https://github.com/vsg-dev/VulkanSceneGraph) - The VulkanSceneGraph library itself is capable of being used on its own for standalone graphics applications, and for embedded platforms this may be the desired approach as it will minimize the code base that needs to be QA'd for security and robustness, and minimizes the final executable size. +* [vsgXchange](https://github.com/vsg-dev/vsgXchange) +It is expected that for most desktop applications, users will also want to load a range of 2D image and 3D model data, to support this usage the library adds support for a wide range of image and 3D model formats, using assimp, as well as support for reading data from http/https using libcurl, and reading/writing/processing of GIS imagery and DEMS through the optional GDAL integration. +* [vsgExamples](https://github.com/vsg-dev/vsgExamples) A collection of 59 examples (as of 20th March 2023) that have been written to help test VulkanSceneGraph features as they are developed and as an educational tool for new users. -Also hosted on vsg-dev are more specialist projects: +Also hosted on vsg-dev are more specialized projects: -* [osg2vsg](https://github.com/vsg-dev/osg2vsg) - osg2vsg library for converting data and integrating OpenGL/OSG and Vulkan/VSG applications. vsgXchange will automatically add support for reading data using the the OpenSceneGraph's loader when osg2vsg has been built and installed before vsgXchange. +* [osg2vsg](https://github.com/vsg-dev/osg2vsg) - osg2vsg library for converting data and integrating OpenGL/OSG and Vulkan/VSG applications. vsgXchange will automatically add support for reading data using the OpenSceneGraph's loader when osg2vsg has been built and installed before vsgXchange. * [vsgImGui](https://github.com/vsg-dev/vsgImGui) - ImGui and ImPlot integration with the VulkanSceneGraph * [vsgQt](https://github.com/vsg-dev/vsgQt) - Qt5/Qt6 integration with the VulkanSceneGraph +* [vsgPoints](https://github.com/vsg-dev/vsgPoints) 3d point cloud loading and rendering for VulkanSceneGraph. * [vsgUnity](https://github.com/vsg-dev/vsgUnity) - plugin for the Unity Editor for exporting VulkanSceneGraph models -* [MyFirstVsgApplication](https://github.com/vsg-dev/MyFirstVsgApplication) - simple standalone example illustrating the CMake and C++ required. -* [vsgFramework](https://github.com/vsg-dev/vsgFramework) - template project that uses CMake FetchContent to pull in all the main libraries associated with VulkanSceneGraph and dependencies and builds them together. +* [MyFirstVsgApplication](https://github.com/vsg-dev/MyFirstVsgApplication) - simple standalone example illustrating the CMake and C++ code required for a basic application. +* [vsgFramework](https://github.com/vsg-dev/vsgFramework) - template project that uses CMake FetchContent to pull in all the main libraries associated with VulkanSceneGraph and its dependencies and builds them together. ## Community projects: * [vsgSDL](https://github.com/ptrfun/vsgSDL) SDL integration with VulkanSceneGraph. @@ -45,17 +46,18 @@ Also hosted on vsg-dev are more specialist projects: ## 3rd party dependencies -The VulkanSceneGraph library uses Vulkan, C++17 and CMake as external dependencies. The Vulkan C headers are used rather then the Vulkan C++ header which is unnecessary as the Vulkan scene graph provideds its own encapsulation of Vulkan objects in a way that is consistent with how they are used in the scene graph. +The VulkanSceneGraph library uses Vulkan, C++17 and CMake as external dependencies. The Vulkan C headers are used rather than the Vulkan C++ header which is unnecessary as the VulkanSceneGraph provides its own encapsulation of Vulkan objects in a way that is consistent with how they are used in the scene graph. -For runtime shader compilation support the [glslang](https://github.com/KhronosGroup/glslang) library, originally an optionally external dependency, but since VulkanSceneGraph-1.0.3 is now built internally as a submodule, this is compiled in by default but can be toggled off by setting the CMake VSG_SUPPORTS_ShaderCompiler variable to 0 before building the source. Compiling glslang within the VulkanSceneGraph library resolved problems with inconsistent 3rd party packaging of glslang, so now users can have seamlessly experience across platforms. +For runtime shader compilation support the [glslang](https://github.com/KhronosGroup/glslang) library is used, originally as an optional external dependency, but since VulkanSceneGraph-1.0.3 it is now built internally as a submodule, this is compiled in by default but can be toggled off by setting the CMake VSG_SUPPORTS_ShaderCompiler variable to 0 before building the source. Compiling glslang within the VulkanSceneGraph library resolved problems with inconsistent 3rd party packaging of glslang, so now users can have a seamless experience across platforms. The additional VulkanSceneGraph projects add their own dependencies: | Project | Required | Optional | | [VulkanSceneGraph](https://github.com/vsg-dev/VulkanSceneGraph) | C++17, CMake, Vulkan | glslang integrated as a submodule | | [vsgXchange](https://github.com/vsg-dev/vsgXchange) | VulkanSceneGraph | curl, assimp, gdal, freetype, OpenEXR, osg2vsg | -| [vsgImGui](https://github.com/vsg-dev/vsgImGui) | VulkanScenegraph, ImGui integrated as a submodule | | +| [vsgImGui](https://github.com/vsg-dev/vsgImGui) | VulkanScenegraph, ImGui & ImPlot integrated as a submodule | | | [vsgQt](https://github.com/vsg-dev/vsgQt) | VulkanSceneGraph, Qt5.10 or later, Qt6 | | +| [vsgPoints](https://github.com/vsg-dev/vsgPoints) | VulkanSceneGraph | | | [vsgExamples](https://github.com/vsg-dev/vsgExamples) | VulkanSceneGraph | vsgXchange, vsgImGui | --- diff --git a/1_SettingTheScene/HelloWorld.md b/1_SettingTheScene/HelloWorld.md index c86c35e..37b0530 100644 --- a/1_SettingTheScene/HelloWorld.md +++ b/1_SettingTheScene/HelloWorld.md @@ -4,19 +4,19 @@ title: Hello World permalink: /SettingTheScene/HelloWorld --- -To download the tutorial exercises clone the vsgTutorial repository, this contains both the book contents and the exercises: +To download the tutorial exercises, clone the vsgTutorial repository. It contains both the book contents and the exercises: ~~~ sh cd ${PROJECT_DIR} git clone https://github.com/vsg-dev/vsgTutorial.git ~~~ -To build the hello world exercise change into the exercise directory, and use the following cmake script to build a stand alone application: +To build the hello world exercise change into the exercise directory, and use the following CMake script to build a standalone application: ~~~ cmake {% include_relative 01_hello_world/CMakeLists.txt %} ~~~ -To build the application change into source diretory, run cmake then make: +To build the application change into source directory, run CMake then make: ~~~ sh cd vsgTutorial/1_SettingTheScene/01_hello_world @@ -28,7 +28,7 @@ The hello world exercise is just a single main() function that has three section 1. create the scene graph 1. create and setup the viewer to render the scene graph -1. executes the frame loop which does the handling of GUI events and rendering. +1. execute the frame loop which does the handling of GUI events and rendering. ~~~ cpp {% include_relative 01_hello_world/hello_world.cpp %} diff --git a/1_SettingTheScene/HighLevelAPIs.md b/1_SettingTheScene/HighLevelAPIs.md index 9c229c7..1b2976f 100644 --- a/1_SettingTheScene/HighLevelAPIs.md +++ b/1_SettingTheScene/HighLevelAPIs.md @@ -4,58 +4,58 @@ title: High-level APIs permalink: /SettingTheScene/HighLevelAPIs --- -Developers wishing to add graphics capabilities to their applications have to either deal directly with the low-level APIs to drive the graphics and compute hardware, or choose from a collection of higher level APIs that are more focused on the needs of application developers than the underlying low-level APIs. A good high-level APIs will not only enable developer to be more productive but also provide better out of the box performance and visual quality, with the high-level API packaging up the expertise and time put in by specialists in high performance graphics and compute. +Developers wishing to add graphics capabilities to their applications have to either deal directly with the low-level APIs to drive the graphics and compute hardware, or choose from a collection of higher level APIs that are more focused on the needs of application developers than the underlying low-level APIs. A good high-level API will not only enable developers to be more productive but also provide better out of the box performance and visual quality, with the high-level API packaging up the expertise and time put in by specialists in high performance graphics and compute. ### Scene Graphs -A common concept utilized by high-level graphics APIs is a Scene Graph. Scene Graphs are an example of Directed Acylic Graph (DAG), where a tree like hierarchy is used to represent the scene. Nodes in the graph made be internal group nodes, support culling, such as view frustum or level of detail culling, through to behavior like switches or sequences, or represent state or geometries that are passed to the GPU for rendering. +A common concept utilized by high-level graphics APIs is a Scene Graph. Scene Graphs are an example of a Directed Acyclic Graph (DAG), where a tree like hierarchy is used to represent the scene. Nodes in the graph may be internal group nodes, support culling, such as view frustum or level of detail culling, through to behavior like switches or sequences, or represent state or geometries that are passed to the GPU for rendering. ### Features vs Generality -High-level APIs may choose to remain quite minimal in feature set and leave more functionality for the application developer to implement, while others build in many different areas of functionality. Broadly speaking the wider the range features provided by an API the more domain specific it becomes as each additional feature will choose a particular approach or 3rd party dependency that is likely to work well for some domains more than others. The more features bundled together the more feature choices are made for you and more likely they'll be inappropriate for your needs and just bloat the codebase and binaries. The advantage of the graeter feature integration is potentially providing a cohessive system of features that work well together. +High-level APIs may choose to remain quite minimal in feature set and leave more functionality for the application developer to implement, while others build in many different areas of functionality. Broadly speaking the wider the range of features provided by an API the more domain specific it becomes as each additional feature will choose a particular approach or 3rd party dependency that is likely to work better for some domains than others. The more features are bundled together, the more choices are made for you, and the more likely it is they'll be inappropriate for your needs and just bloat the codebase and binaries. The advantage of the greater feature integration is potentially providing a cohesive system of features that work well together. -An example of high-level API with relatively modest feature set and tight focus would be scene graph like Open Inventor or Performer, while one that encompass a extensive feature set would a game engine like Unreal or Unity. These two approaches aren't incompatible - a game engine could contain its own scene graph or a 3rd party scene graph, the later approach was taken by [Delta3D](https://en.wikipedia.org/wiki/Delta3D) project that built upon the OpenSceneGraph. +Examples of high-level APIs with a relatively modest feature set and tight focus would be scene graphs like Open Inventor or Performer, while ones that encompass an extensive feature set would be game engines like Unreal or Unity. These two approaches aren't incompatible - a game engine could contain its own scene graph or a 3rd party scene graph, the latter approach was taken by the [Delta3D](https://en.wikipedia.org/wiki/Delta3D) project that built upon the OpenSceneGraph. -### Abstraction vs Encapslation +### Abstraction vs Encapsulation -Some high-level APIs choose to build in low-level API abstraction layers so they can support multiple APIs such as Vulkan, OpenGL, multiple versions of Direct3D, Metal etc - this brings us to the perverse realm of the hardware abstraction layer abstraction layer. Such extra abstraction layers add cpmplexity and move the application developer further away from what they are attempting to run on the hardware. This approach also adds more code for the high-level API maintainer to write, test, debug and support, and far greater range of permutations of hardware and APIs to test and support. This poor engineering approach has been born from the real or periecved issues with how well the cross platform low-level APIs are supported across platforms, it's a workaround to the attempts of Microsoft/Apple/etc. to exert vendor lock-in. +Some high-level APIs choose to build in low-level API abstraction layers so they can support multiple APIs such as Vulkan, OpenGL, multiple versions of Direct3D, Metal etc. - this brings us to the perverse realm of the hardware abstraction layer abstraction layer. Such extra abstraction layers add complexity and move the application developer further away from what they are attempting to run on the hardware. This approach also adds more code for the high-level API maintainer to write, test, debug and support, and a far greater range of permutations of hardware and APIs to test and support. This poor engineering approach has been born from the real or perceived issues with how well the cross platform low-level APIs are supported across platforms, it's a workaround to the attempts of Microsoft/Apple/etc. to exert vendor lock-in. -An alternative approach used by some high-level APIs is to simply encapsulate the low-level APIs rather than abstract from them, this keeps the application developer closer to a 1:1 relationship with the data and processing they are managing on the hardware. Taking this path could limit portabilitiy to particular OSs, or hardware, but thankfully with OpenGL and Vulkan they are designed to be both OS agnostic and able to handle a wide range of hardware so the choice to encapsualte OpenGL or Vulkan need not limit portablity over the low-level API abstraction approach. +An alternative approach used by some high-level APIs is to simply encapsulate the low-level APIs rather than abstract from them, this keeps the application developer closer to a 1:1 relationship with the data and processing they are managing on the hardware. Taking this path could limit portability to particular OSs, or hardware, but thankfully with OpenGL and Vulkan they are designed to be both OS agnostic and able to handle a wide range of hardware so the choice to encapsulate OpenGL or Vulkan need not limit portability over the low-level API abstraction approach. ## A Brief History of High-level APIs -One of the first widely used high-level APIs for real-time 3D graphics was IRIS [Inventor](https://en.wikipedia.org/wiki/Open_Inventor) that was started at SGI in the late 1980's and follows a scene graph approach to represent a 3D scene. Created to make development of 3D graphics applications easier as the low-level nature of IRIS GL was a barrier to entry. Succeeded by Open Inventor which adopts OpenGL as its base and became widely adopted in the scientific and engineering sectors where ease of use was more critical than maximizing performance. Inventor's strength lay its embodiment of the scene graph concept in such a flexible and extensible way. It's weakness was in the way its design limited performance and scalaibility. +One of the first widely used high-level APIs for real-time 3D graphics was IRIS [Inventor](https://en.wikipedia.org/wiki/Open_Inventor) that was started at SGI in the late 1980's and followed a scene graph approach to represent a 3D scene. It was created to make development of 3D graphics applications easier as the low-level nature of IRIS GL was a barrier to entry. Then it was succeeded by Open Inventor which used OpenGL as its base and became widely adopted in the scientific and engineering sectors where ease of use was more critical than maximizing performance. Inventor's strength lay in its embodiment of the scene graph concept in such a flexible and extensible way. Its weakness was in the way its design limited performance and scalability. -[Performer](https://en.wikipedia.org/wiki/OpenGL_Performer) created in 1991 by developers from the Inventor development group to focus on performance rather than usability. Performer was designed to work multithreaded working on multiple CPU and multiple GPU's in order to scale to utilize SGI's high end hardware such as the Onyx line of graphics "super" computers. These have far less performance and capabilities than modern phones, but during the mid 90's they were the world's most powerful graphics systems. +[Performer](https://en.wikipedia.org/wiki/OpenGL_Performer), created in 1991 by developers from the Inventor development group, focused on performance rather than usability. Performer was designed to work multithreaded, scaling to multiple CPUs and multiple GPUs in order to utilize SGI's high-end hardware such as the Onyx line of graphics "super" computers. These have far less performance and capabilities than modern phones, but during the mid-90's they were the world's most powerful graphics systems. -[Cosmo3D](https://en.wikipedia.org/wiki/OpenGL%2B%2B) - mid 1990's yet another SGI scene graph! Created to provide a unified scene graph that was scalable and high performance like perfromer, and better usability like Inventor. SGI worked with other vendors to create a standardised OpenGL++ scene graph, using Cosmo3D as the base. +[Cosmo3D](https://en.wikipedia.org/wiki/OpenGL%2B%2B) - mid 1990's there was yet another SGI scene graph! Created to provide a unified scene graph that was scalable and fast like Performer, and with better usability like Inventor. SGI worked with other vendors to create a standardised OpenGL++ scene graph, using Cosmo3D as the base. -[Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit_(graphics_API)) - late 1990's. SGI and Microsoft collaboration to create a low-level API successor to OpenGL, and high-level successor to Inventor/Performer. High-level used a Cosmo3D as starting place. Mcrisoft strung SGI along for a year before the project collapsed, with Microsoft using the IP agreement to enable more advancd features to make it into Direct3D. Microsoft's plan all along? +[Fahrenheit](https://en.wikipedia.org/wiki/Fahrenheit_(graphics_API)) - late 1990's. SGI and Microsoft collaborated to create a low-level API successor to OpenGL, and high-level successor to Inventor/Performer. At the high-level they used Cosmo3D as a starting place. Microsoft strung SGI along for a year before the project collapsed, with Microsoft using the IP agreement to enable more advanced features to make it into Direct3D. Microsoft's plan all along? -The collapse of the Fahrenheit project left a vacuum in the world of standardized high-level APIs, the proprietary scene graph had failed to deliver a standardized solution as had been done for low-level APIs. In the late 1990's Open Sourc/Free Software was growing in significance and offered an entirely different approach to creating software, a number of hobby level projects sprung up like [Plib](https://sourceforge.net/projects/plib/) through to [CystalSpace](https://en.wikipedia.org/wiki/Crystal_Space) but none had anything close to capabilities of the profressional APIs like Inventor, Performaner and other propritary APIs like Vega. +The collapse of the Fahrenheit project left a vacuum in the world of standardized high-level APIs, the proprietary scene graph world had failed to deliver a standardized solution as had been done for low-level APIs. In the late 1990's Open Source/Free Software was growing in significance and offered an entirely different approach to creating software, a number of hobby level projects sprung up like [Plib](https://sourceforge.net/projects/plib/) through to [CrystalSpace](https://en.wikipedia.org/wiki/Crystal_Space) but none had anything close to the capabilities of the professional APIs like Inventor, Performer and other proprietary APIs like Vega. -In 1999 the Fraunhofer Institute created a consortium to develop [OpenSG](https://en.wikipedia.org/wiki/OpenSG) project, from the outset it had high asperations for delivering an Open Soucrce cross platform, scalable, high performance scene graph - embracing all the facets that the industry had been wanting from Fahrenheit. +In 1999 the Fraunhofer Institute created a consortium to develop the [OpenSG](https://en.wikipedia.org/wiki/OpenSG) project, from the outset it had high aspirations for delivering an Open Source cross platform, scalable, high performance scene graph - embracing all the facets that the industry had been wanting from Fahrenheit. -At the same time, completely independently and initially unware of OpenSG project, Don Burns, an SGI engineer, working in his spare time on a home built Hang Gliding Simulator created a small scene graph library, on top of OpenGL, simply because Performer hadn't yet been ported to the Linux PC. Don sought assistance from Robert Osfield, a fellow software engineer and Hang Glider pilot with knowledge of aredyanmics to help with the development of the flight model. Robert ported the nascent scene graph library to Windows and the decision was made to publish the library as Open Source under the LGPL license. Originally named SG, for Scene Graph, Open was added to name and the [OpenSceneGraph](https://en.wikipedia.org/wiki/OpenSceneGraph) project came into existence with a tar.gz file published on a single web page. Two engineers in their spare time hacking away on a hang glider sim with no lofty goal beyond just getting a hang glider, a flying site with a hill and a few trees rendered. +At the same time, completely independently and initially unaware of the OpenSG project, Don Burns, an SGI engineer, working in his spare time on a home-built Hang Gliding Simulator, created a small scene graph library, on top of OpenGL, simply because Performer hadn't yet been ported to the Linux PC. Don sought assistance from Robert Osfield, a fellow software engineer and Hang Glider pilot with knowledge of aerodynamics to help with the development of the flight model. Robert ported the nascent scene graph library to Windows and the decision was made to publish the library as Open Source under the LGPL license. Originally named SG, for Scene Graph, Open was added to the name and the [OpenSceneGraph](https://en.wikipedia.org/wiki/OpenSceneGraph) project came into existence with a tar.gz file published on a single web page. Two engineers in their spare time were hacking away on a hang glider sim with no lofty goal beyond just getting a hang glider, a flying site with a hill and a few trees rendered. -In 2000 the vis-sim and GIS sectors desperately needed a modern, professional grade graphics scene graph alternative to the proprietary scene graph projects which were poorly supported, slow moving or failing. OpenSG and OpenSceneGraph both were contenders but paradoxically the grand plans of the OpenSG project meant its release cycle was too slow for an industry desperate for a new scene graph, while the OpenSceneGraph was developed in spare time, with no formal plans or funding but a rapid release cycle and responsive lead develolpers and gained acceptance in the vis-sim and GIS sector. +In 2000 the vis-sim and GIS sectors desperately needed a modern, professional grade graphics scene graph alternative to the proprietary scene graph projects which were poorly supported, slow moving or failing. OpenSG and OpenSceneGraph both were contenders but paradoxically the grand plans of the OpenSG project meant its release cycle was too slow for an industry desperate for a new scene graph, while the OpenSceneGraph was developed in spare time, with no formal plans or funding but a rapid release cycle and responsive lead developers and gained acceptance in the vis-sim and GIS sector. -By 2001 the OpenSceneGarph had gained a commercial following sufficient for Robert and then Don to leave their full-time jobs and go fultime and pay the bills through consulting, bespoke development work and training services. Through the first decade of the new milenium the project gained a following in both commercial and open source applications with thousands of developers worldwide using it, and over 500 developers having contributed directly to the software code base. The strength of the OpenSceneGraph lay in the expertise and responsiveness of lead developers and the choice to encpasulate OpenGL in a clean way, without attempting to abstract away from the abstraction layer. +By 2001 the OpenSceneGraph had gained a commercial following sufficient for Robert and then Don to leave their full-time jobs and go fulltime and pay the bills through consulting, bespoke development work and training services. Through the first decade of the new millennium the project gained a following in both commercial and open-source applications with thousands of developers worldwide using it, and over 500 developers having contributed directly to the software code base. The strength of the OpenSceneGraph lay in the expertise and responsiveness of lead developers and the choice to encapsulate OpenGL in a clean way, without attempting to abstract away from the API layer. -In 2005 [Unity](https://en.wikipedia.org/wiki/Unity_(game_engine)) was released, a game engine and tools with a licensing model that was free from hobby/small scale use. Unity evolved over the years from a niche of the market to wide market acceptance. +In 2005 [Unity](https://en.wikipedia.org/wiki/Unity_(game_engine)) was released, a game engine and tools with a licensing model that was free for hobby/small scale use. Unity evolved over the years from a niche of the market to wide market acceptance. -Around the middle of the second decade OpenGL's evolution was under serious strain with CPU and GPUs capabilities so far removed from the capabilities of hardware in the early 90's. Driver quality across vendors and performance remaind a serious issue for application developers. Small incremental changes were no longer sufficient to keep up, and the attempt at introducing the OpenGL Core Profile only fractured and complicated the task of supporting OpenGL. For high-level APIs like the OpenSceneGraph that focused entirely on OpenGL and OpenGL ES the troubles with OpenGL and its own age began to make it more cumbersome to support and use. +Around the middle of the second decade OpenGL's evolution was under serious strain with CPU and GPUs capabilities so far removed from the capabilities of hardware in the early 90's. Driver quality across vendors and performance remained a serious issue for application developers. Small incremental changes were no longer sufficient to keep up, and the attempt at introducing the OpenGL Core Profile only fractured and complicated the task of supporting OpenGL. For high-level APIs like the OpenSceneGraph that focused entirely on OpenGL and OpenGL ES the troubles with OpenGL and its own age began to make it more cumbersome to support and use. -In 2014 the [Unreal Engine 4](https://en.wikipedia.org/wiki/Unreal_Engine) was released with a new licensing model, with the full source code released and royalties charged on game revenue. Having a professional grade game engine and tools widely available changed the competitive landscape for high-level APIs. +In 2014 the [Unreal Engine 4](https://en.wikipedia.org/wiki/Unreal_Engine) was released with a new licensing model, with the full source code released and royalties charged on game revenue. Having a professional grade game engine and tools widely available changed the competitive landscape for high-level APIs. -In 2016 Khronos released Vulkan as the successor to OpenGL, which then presented the question for high-level APIs - do they add yeat another low-level hardware abstraction layer to the ones they already support, or create new high-level APIs specifically for Vulkan building upon its strengths. Game engines that adopted Vulkan showed modest performance gains over OpenGL and have increasingly become the preferred choice for cross platform games. +In 2016 Khronos released Vulkan as the successor to OpenGL, which then presented the question for high-level APIs - do they add yet another low-level hardware abstraction layer to the ones they already support or create new high-level APIs specifically for Vulkan building upon its strengths. Game engines that adopted Vulkan showed modest performance gains over OpenGL and have increasingly become the preferred choice for cross platform games. -The advent of Vulkan and the clear need for it given OpenGL's failings presented the OpenSceneGraph with a dilemma. THe OpenSceneGraph is written to be an OpenGL scene graph - it emodies the OpenGL++ dream held be egnieers in the 90's, the whole design is built around the OpenGL state machine and the OpenGL FIFO and threading constraints. Vulkan has a completely different API and architecture to OpenGL and a significantly lower CPU overhead. For the OpenSceneGraph to adopt Vulkan and still support OpenGL would require a major rewrite of the API and internal architecture and implementation, handling two very different low-level APIs would require significant compromsises in the way features are exposed in order to support both OpenGL and Vulkan. Such considerations would make the final high-level software incompatible with older versions of the OpenSceneGraph and deliver performance that is less than either OpenGL or Vulkan is capable of due to the extra abstraction layer that would need to be introduced. +The advent of Vulkan and the clear need for it given OpenGL's failings presented the OpenSceneGraph with a dilemma. The OpenSceneGraph is written to be an OpenGL scene graph - it embodies the OpenGL++ dream held by engineers in the 90's, the whole design is built around the OpenGL state machine and the OpenGL FIFO and threading constraints. Vulkan has a completely different API and architecture to OpenGL and a significantly lower CPU overhead. For the OpenSceneGraph to adopt Vulkan and still support OpenGL would require a major rewrite of the API and internal architecture and implementation, handling two very different low-level APIs would require significant compromises in the way features are exposed in order to support both OpenGL and Vulkan. Such considerations would make the final high-level software incompatible with older versions of the OpenSceneGraph and deliver performance that is less than either OpenGL or Vulkan is capable of due to the extra abstraction layer that would need to be introduced. -It was clear to OpenSceneGraph project lead Robert Osfield that a new scene graph built for Vulkan using modern C++ would be the best choice for exposing all the new capabilities that Vulkan brings and to keep the CPU overheads as low as possible so that performance could fully take advantage of Vulkan's low CPU overhead. For instance if your existing scene graph has a CPU overhead of 10ms, and OpenGL adds another 5ms then if the best case improvement from going to Vulkan with a 1ms CPU overhead would be a 10.5ms frametime - a 43% improvement, even though Vulkan might be 10 X faster. To get a 5 X improvement overall you also have to make the scene graph 10 X faster as well. +It was clear to OpenSceneGraph project lead Robert Osfield that a new scene graph built for Vulkan using modern C++ would be the best choice for exposing all the new capabilities that Vulkan brings and to keep the CPU overheads as low as possible so that performance could fully take advantage of Vulkan's low CPU overhead. For instance, if your existing scene graph has a CPU overhead of 10ms, and OpenGL adds another 5ms then the best-case improvement from going to Vulkan with a 1ms CPU overhead would be a 10.5ms frame-time - a 43% improvement, even though Vulkan might be 10 X faster. To get a 5 X improvement overall you also have to make the scene graph 10 X faster as well. -In Spring 2018 Robert Osfield was approached by a company that used OpenSceneGraph for vis-sim that want to fund the initial development of a new Vulkan based scene graph. Work began in on the VulkanSceneGrapph in the [3rd week of May 2018](https://github.com/vsg-dev/VulkanSceneGraph/commit/5fb0bdb1b49741ac5f8911c21128511a46823825). Four and half very intense years later [VulkanSceneGraph-1.0](https://github.com/vsg-dev/VulkanSceneGraph/releases/tag/VulkanSceneGraph-1.0.0) was released on the 13th November 2022. +In Spring 2018 Robert Osfield was approached by a company that used OpenSceneGraph for vis-sim that wanted to fund the initial development of a new Vulkan based scene graph. Work began on the VulkanSceneGraph in the [3rd week of May 2018](https://github.com/vsg-dev/VulkanSceneGraph/commit/5fb0bdb1b49741ac5f8911c21128511a46823825). Four and a half very intense years later [VulkanSceneGraph-1.0](https://github.com/vsg-dev/VulkanSceneGraph/releases/tag/VulkanSceneGraph-1.0.0) was released on the 13th November 2022. --- diff --git a/1_SettingTheScene/LowLevelAPIs.md b/1_SettingTheScene/LowLevelAPIs.md index f875009..e092997 100644 --- a/1_SettingTheScene/LowLevelAPIs.md +++ b/1_SettingTheScene/LowLevelAPIs.md @@ -4,17 +4,17 @@ title: Low-level APIs permalink: /SettingTheScene/LowLevelAPIs --- -Low-level graphics and compute APIs provide an interface with hardware drivers that manage data transfers and processing on highly parallelized graphics and compute hardware. Low-level APIs may be tied to specific operatings systems and/or specific sets of hardware, through to being capable of running on multiple operating systems and across a wide range of hardware. OpenGL and Vulkan are examples of the latter that are OS agnostic and provide extensible hardware abstraction. +Low-level graphics and compute APIs provide an interface with hardware drivers that manage data transfers and processing on highly parallelized graphics and compute hardware. Low-level APIs may be tied to specific operatings systems and/or specific sets of hardware, through to being capable of running on multiple operating systems and across a wide range of hardware. OpenGL and Vulkan are examples of the latter that are OS agnostic and provide extensible hardware abstraction. ### Level of Hardware Abstraction vs Complexity -Low-level APIs focus on interfacing with hardware efficiently, rather than making it convenient to develop graphics and compute applications. Older low-level APIs like OpenGL provide a higher level of abstraction than modern low-level APIs like Vulkan and Direct2D 12, which are designed to enable greater low-level control over data, processing and synchronization with the hardware. +Low-level APIs focus on interfacing with hardware efficiently, rather than making it convenient to develop graphics and compute applications. Older low-level APIs like OpenGL provide a higher level of abstraction than modern low-level APIs like Vulkan and Direct3D 12, which are designed to enable greater low-level control over data, processing and synchronization with the hardware. These modern APIs can be seen as more focused on hardware performance and capabilities than on supporting the needs of application developers, so while lifting the ceiling on raw performance and quality they require significantly greater expertise from application developers in order to use them. -### Incremental vs Monolythic +### Incremental vs Monolithic -OpenGL and Vulkan are written to evolve incrementally and in a fine grained way, with vendor specific extensions being exposed before these features are worked on by groups of vendors and before these features eventually are merged into the core. This contrasts with a monolithic approach taken by Direct3D with major versions changing the API and features exposed, to use the latest features you have no choice but to update to the new API version. +OpenGL and Vulkan are written to evolve incrementally and in a fine grained way, with vendor specific extensions being exposed before these features are worked on by groups of vendors and before these features eventually are merged into the core. This contrasts with a monolithic approach taken by Direct3D with major versions changing the API and features exposed, to use the latest features you have no choice but to update to the new API version. For applications that will be developed over many years the approach taken with OpenGL and Vulkan helps keep the applications relevant without requiring major rewrites as new features can be introduced one by one as software & hardware evolves. The discrete jumps of Direct3D would require major rewrites in order to take advantage of new features, not a major issue for application types like games that get written once and have a short shelf life, but would be a hindrance for long lived applications. @@ -22,21 +22,21 @@ For applications that will be developed over many years the approach taken with In the 1980's SGI created IRIS GL (https://en.wikipedia.org/wiki/IRIS_GL), a C API for 2D and 3D rendering on SGI hardware. -In 1992 SGI introduced OpenGL - an open and cross platform C API capable of rendering textured triangles and basic lighting on a variety of hardware and OS's. Throughout the early nineties SGI and OpenGL saw massive adoption and growth for both OpenGL adoption and SGI as a company. +In 1992 SGI introduced OpenGL - an open and cross platform C API capable of rendering textured triangles and basic lighting on a variety of hardware and OS's. Throughout the early nineties SGI and OpenGL saw massive adoption and growth for both OpenGL and SGI as a company. -In 1996 Microsoft introduced Direct3D - new era of vendor lock-in, while early rev's weren't competitive to OpenGL, the industry sleepwalked into adoption by Microsoft's anti-competitive practices. +In 1996 Microsoft introduced Direct3D - starting a new era of vendor lock-in, while early rev's weren't competitive to OpenGL, the industry sleepwalked into adoption by Microsoft's anti-competitive practices. During the early 2000s Direct3D progressively dominated the games industry, with OpenGL left serving professional graphics applications. -In August 2009 [OpenCL](https://en.wikipedia.org/wiki/OpenCL) was launched by Apple and in 2010 it was adopted by Khronos Group as a cross-vendor Compute on GPU API to compliment OpenGLs Graphics on GPU capabilities. +In August 2009 [OpenCL](https://en.wikipedia.org/wiki/OpenCL) was launched by Apple and in 2010 it was adopted by Khronos Group as a cross-vendor Compute on GPU API to complement OpenGL's Graphics on GPU capabilities. In 2013 AMD started working on [Mantle](https://en.wikipedia.org/wiki/Mantle_(API)) to develop an API with much lower overhead that was better able to maximize utilization of modern multi-core CPUs and super fast GPUs. -In 2014, after many years of supporting OpenGL, Apple joined the vendor lock-in game, creating it's own low-level [Metal API](https://en.wikipedia.org/wiki/Metal_(API)), and began a march towards deprecating OpenGL on Apple systems. +In 2014, after many years of supporting OpenGL, Apple joined the vendor lock-in game, creating its own low-level [Metal API](https://en.wikipedia.org/wiki/Metal_(API)), and began a march towards deprecating OpenGL on Apple systems. -Khnoros adopted Mantle as the basis for a new cross-vendor, cross platform successor to OpenGL, releasing the [Vulkan-1.0](https://en.wikipedia.org/wiki/Vulkan) spec in February 2016. Vulkan is lower level than OpenGL, applications take over more responsibilities that previously OpenGL drivers would have to manage, but provides more freedom and control over data and multi-threaded control of data and commands being passed to/from the GPU. Vulkan combines Compute and Graphics in one single coherent API. +Khnoros adopted Mantle as the basis for a new cross-vendor, cross platform successor to OpenGL, releasing the [Vulkan-1.0](https://en.wikipedia.org/wiki/Vulkan) spec in February 2016. Vulkan is lower level than OpenGL, applications take over more responsibilities that previously OpenGL drivers would have had to manage, but provides more freedom and control, such as multi-threaded control of data and commands being passed to/from the GPU. Vulkan combines Compute and Graphics in one single coherent API. -In Feb. 2018 MoltenVK library was released enabling Vulkan to run on top of Metal on macOS and iOS systems breaking the vendor lock-in and enabling Vulkan to work on all major hardware and software platforms. +In February 2018 the MoltenVK library was released enabling Vulkan to run on top of Metal on macOS and iOS systems breaking the vendor lock-in and enabling Vulkan to work on all major hardware and software platforms. --- diff --git a/1_SettingTheScene/PerformancePrinciples.md b/1_SettingTheScene/PerformancePrinciples.md index 83c1595..93d00bd 100644 --- a/1_SettingTheScene/PerformancePrinciples.md +++ b/1_SettingTheScene/PerformancePrinciples.md @@ -4,29 +4,29 @@ title: Performance Principles permalink: /SettingTheScene/PerformancePrinciples --- -Efficiency of the design and implementation is critical to the projects success so took centre stage when evaluation different approaches to design and implementation, with the aspiration of making each VulkanSceneGraph features 10 X faster than the equivalent feature in the OpenSceneGraph. Understanding what is happening in hardware to the data and how it is processed in each stage of the application is crucial to achieving this goal. +Efficiency of the design and implementation is critical to the project's success so took centre stage when evaluating different approaches to design and implementation, with the aspiration of making each VulkanSceneGraph feature 10 X faster than the equivalent feature in the OpenSceneGraph. Understanding what is happening in hardware to the data and how it is processed in each stage of the application is crucial to achieving this goal. CPU bottlenecks with scene graph application predominantly occur during traversals of the scene graph, this is due to: * scene graphs can contain tens or hundreds of thousands of objects and use many GBs of memory spread across nodes, textures and geometry data -* traversing large scene graph pushes the limits of memory bandwidth and CPU cache coherency, this was true in the 90's and is even more critical in 2020's +* traversing large scene graphs pushes the limits of memory bandwidth and CPU cache coherency, this was true in the 90's and is even more critical in 2020's * CPU features like pre-fetch, branch prediction and instruction parallelization are sensitive to how data is arranged and how control flows are structured -Different CPUs have different strengths and weakness, some cope well with diffuse memory access and large numbers of branches, others struggle with such challenging code and data. Taking care of how data is stored and processed to avoid stressing the CPU and memory architecture can substantially improve CPU utilization and throughput. A series of design decisions were made for the VulkanSceneGraph to help make this happen: +Different CPUs have different strengths and weaknesses, some cope well with diffuse memory access and large numbers of branches, others struggle with such challenging code and data. Taking care of how data is stored and processed to avoid stressing the CPU and memory architecture can substantially improve CPU utilization and throughput. A series of design decisions were made for the VulkanSceneGraph to help make this happen: -* From the vsg::Object base class through to scene graphs nodes are kept as small as possible. Data members like names, description, masks and callbacks are avoided in most commonly used classes. +* From the vsg::Object base class through to scene graph nodes, classes are kept as small as possible. Data members like names, descriptions, masks and callbacks are avoided in the most commonly used classes. * A flexible meta data scheme is provided by a vsg::Auxiliary class that can be used on all objects when required, but in most cases will simply be the overhead of a null pointer. This allows developers the flexibility to add names, descriptions etc when needed, without all objects paying the memory penalty. -* Scene graph callbacks are eliminated, with easy subclassing from scene graph nodes making this possible. Not having scene graph callbacks on nodes avoids the need to hold pointers to them and to check those pointers to see if custom behaivor is required. -* Scene graph node masks only exist on specific node types where they are most useful, again this reduces memory footprint of nodes and avoids conditional statements. +* Scene graph callbacks are eliminated, with easy subclassing from scene graph nodes making this possible. Not having scene graph callbacks on nodes avoids the need to hold pointers to them and to check those pointers to see if custom behaviour is required. +* Scene graph node masks only exist on specific node types where they are most useful, again reducing memory footprint of nodes and avoiding conditional statements. * Dedicated nodes for scene graph culling like view frustum and LOD culling rather than having this functionality on all nodes avoids the need for a bounding volume data member on all scene graph nodes, and avoids the need for checking if a cull test is required and any branching based on a cull test. -* Block memory allocator, vsg::Allocator, groups objects of similar type together into pre allocated blocks in memory. Nodes are packed together, geometry and texture data are packed together etc. +* A block memory allocator, the vsg::Allocator, groups objects of similar type together into pre allocated blocks in memory. Nodes are packed together, geometry and texture data are packed together etc. Together these design decisions ensure: * minimal object size so more objects can fit in main memory and crucially the CPU caches - vsg::Node takes just 24 bytes vs osg::Node 208 bytes. -* objects that will be operated on togeher are stored in memory together to increase the probability that cache lines will contain objects that will be next accessed. +* objects that will be operated on together are stored in memory together to increase the probability that cache lines will contain objects that will be next accessed. * conditional statements are reserved to just the places where they are required, rather than everywhere just in case they might be needed, so there is less branching, and branch prediction has a better chance of following the correct path. -The end result is scene graph traversals that are around 10 times faster than the equivalent in the OpenSceneGraph. These are just a taste of the many performance related decisions in the VulkanSceneGraph, as you work through the vsgTutorial you'll be introduced to more tips and tricks that have been used, and ones that you can use in your own application development as well. +The end result is scene graph traversals that are around 10 times faster than the equivalent in the OpenSceneGraph. These are just a taste of the many performance related decisions in the VulkanSceneGraph, as you work through the vsgTutorial you'll be introduced to more tips and tricks that have been used, and ones that you can use in your own application development as well. --- diff --git a/1_SettingTheScene/Vulkan.md b/1_SettingTheScene/Vulkan.md index 7ab9bc6..5c45ca6 100644 --- a/1_SettingTheScene/Vulkan.md +++ b/1_SettingTheScene/Vulkan.md @@ -4,7 +4,7 @@ title: Vulkan - graphics and compute API permalink: /SettingTheScene/Vulkan --- -The standards body [Khronos](https://www.khronos.org/) released the successor to OpenGL, Vulkan-1.0 in February 2016, ushering in next generation of Open, Cross Platform API for graphics and compute. +The standards body [Khronos](https://www.khronos.org/) released the successor to OpenGL, Vulkan-1.0 in February 2016, ushering in the next generation of Open, Cross Platform API for graphics and compute. ### Pros: * Very low CPU overhead enables low power consumption and higher performance. @@ -13,9 +13,9 @@ The standards body [Khronos](https://www.khronos.org/) released the successor to Designed from the ground up for multi-threading, with state localized within command buffers and explicit synchronisation primitives. * Cross platform: [source Wikipedia](https://en.wikipedia.org/wiki/Vulkan) -"Vulkan runs natively on Android, Linux, BSD Unix, QNX, Haiku, Nintendo Switch, Raspberry Pi, Stadia, Fuchsia, Tizen, and Windows 7, 8, 10, and 11. MoltenVK provides freely-licensed third-party support for macOS, iOS and tvOS by wrapping over Apple's Metal API." +"Vulkan runs natively on Android, Linux, BSD Unix, QNX, Haiku, Nintendo Switch, Raspberry Pi, Stadia, Fuchsia, Tizen, and Windows 7, 8, 10, and 11. MoltenVK provides freely-licensed third-party support for macOS, iOS and tvOS by wrapping over Apple's Metal API." -* Runtime extension system, enabling fine-grainded support for latest hardware features, including: +* Runtime extension system, enabling fine-grained support for latest hardware features, including: * Ray Tracing * Mesh Shaders @@ -27,14 +27,14 @@ Designed from the ground up for multi-threading, with state localized within com ### Cons: * Low level, responsibility for many tasks moves from driver into application scope. -Developers must explicitly configure settings, allocate and manage memory, transfering of data to/from GPU, dispatching and synchronizing CPU and GPU operations. +Developers must explicitly configure settings, allocate and manage memory, manage transfering of data to/from GPU and dispatching and synchronizing CPU and GPU operations. * Requires more knowledge and code to implement even simple features - 1500 lines of code to just render a textured triangle! ### Useful links: * [VulkanSDK](https://vulkan.lunarg.com/sdk/home) LUNARG's website containing the VulkanSDK - -provides single package with headers and libs for Windows, Linux and macOS. +provides a single package with headers and libs for Windows, Linux and macOS. * [AndroidNDK](https://developer.android.com/ndk/guides/graphics/index.html) - Googles Android NDK diff --git a/1_SettingTheScene/VulkanSceneGraphLibrary.md b/1_SettingTheScene/VulkanSceneGraphLibrary.md index 6827ffa..7fc390b 100644 --- a/1_SettingTheScene/VulkanSceneGraphLibrary.md +++ b/1_SettingTheScene/VulkanSceneGraphLibrary.md @@ -8,36 +8,36 @@ The [VulkanSceneGraph library](https://github.com/vsg-dev/VulkanSceneGraph/) pro ## Feature organization -All VulkanSceneGraph projects follow the same structure - public headers can be found in include/ directories and the implementation can be found in the src/ directories. This pattern is used to make it clear to end users what part they will interface with, and as clear demarcation to library developers & contributors that interfaces and implementations both have distinct roles. When installing the software it will only be the files in the include directories and any built libraries + cmake config files that will be installed. +All VulkanSceneGraph projects follow the same structure - public headers can be found in include/ directories and the implementation can be found in the src/ directories. This pattern is used to make it clear to end users what part they will interface with, and as clear demarcation to library developers & contributors that interfaces and implementations both have distinct roles. When installing the software it will only be the files in the include directories and any built libraries + cmake config files that will be installed. The [vsg library headers](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg) are grouped in the following [include/vsg](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/) subdirectories: Foundational class directories: -* [core](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core) - base classes, smart pointer, data continers, allocators and visitor base classes +* [core](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core) - base classes, smart pointer, data containers, allocators and visitor base classes * [maths](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths) - GLSL style maths classes, similar to glm * [io](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io) - serialization and built-in reader/writers. Scene graph class directories: * [commands](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/commands) - scene graph nodes for Vulkan Commands * [state](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/state) - scene graph objects for setting Vulkan state. -* [nodes](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/) - scene graph nodes like groups, swtiches & transforms +* [nodes](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/) - scene graph nodes like groups, switches & transforms * [text](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/text) - text scene graph nodes * [meshshaders](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/meshshaders) - Khronos Mesh Shader support * [raytracing](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/raytracing) - Khronos Ray Tracing support Application class directories: -* [vk](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/vk) - high level Vulkan integration such vkInstance/vkDevice etc. +* [vk](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/vk) - high level Vulkan integration such as VkInstance/VkDevice etc. * [app](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/app) - application level Vulkan classes * [platform](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/platform) - platform specific Windowing support * [ui](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/ui) - user interface classes such as mouse and keyboard events -* [utils](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/utils) - collection of utilities such intersections through to shader composition and compilation. +* [utils](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/utils) - collection of utilities such as intersections through to shader composition and compilation. * [threading](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/threading) - threading classes and helper functions The sections of the vsgTutorial are grouped in this way so that as you work through you'll be introduced to [Foundational](../foundations.md), [Scene Graph](../scenegraph.md) and [Application](../application.md) areas in turn. ## Naming conventions -All VulkanSceneGraph projects use the following naming convnetions: +All VulkanSceneGraph projects use the following naming conventions: | **Project** | **Library** | **Namespace** | **CMake package**| | VulkanSceneGraph | vsg | vsg:: | find_package(vsg) | @@ -45,22 +45,22 @@ All VulkanSceneGraph projects use the following naming convnetions: | vsgImGui | vsgImGui | vsgImGui:: | find_package(vsgImGui) | | vsgQt | vsgQt | vsgQt:: | find_package(vsgQt) | -All Vulkan related classes in the VulkanSceneGraph follow the naming conventions vkFeatureName -> vsg::FeatureName, for example: +All Vulkan related classes in the VulkanSceneGraph follow the naming conventions VkFeatureName -> vsg::FeatureName, for example: | **Vulkan** | **VulkanSceneGraph** | -| vkInstance | vsg::Instance | -| vkPhysicalDevice | vsg::PhysicalDevice | -| vkDevice | vsg::Device | -| vkFramebuffer | vsg::Framebuffer | -| vkSurface | vsg::Surface | +| VkInstance | vsg::Instance | +| VkPhysicalDevice | vsg::PhysicalDevice | +| VkDevice | vsg::Device | +| VkFramebuffer | vsg::Framebuffer | +| VkSurface | vsg::Surface | -The class and variable naming conventions is predominatly CamelCase but as there are cases where we use snake_case. If a function/template or struct mirrors a Standard C++ feature then snake_case may be used. For the GLSL inspired math support structs are used and have a leading lower case letter i.e. vsg::vec3 and vsg::mat4. +The class and variable naming convention is predominantly CamelCase but there are cases where we use snake_case. If a function/template or struct mirrors a Standard C++ feature, then snake_case may be used. For the GLSL inspired math, support structs are used and have a leading lower case letter i.e. vsg::vec3 and vsg::mat4. ## Public/Protected/Private scope conventions -Classes in the VulkanSceneGraph predominatly follow the declaration of scope in order of public interface through to internal implementation details. The naming of public members variables and methods follow camelCase while protected and private members variables and methods are prefixed with a _ so that their roles can be seen in the declaration and implementation. +Classes in the VulkanSceneGraph predominantly follow the declaration of scope in order of public interface through to internal implementation details. The naming of public member variables and methods follow camelCase while protected and private member variables and methods are prefixed with a _ so that their roles can be seen in the declaration and implementation. -For the same reasons that headers and source files are kept in distinct include and src directories, this convention is used to make it clear to end users and to implementers that public facing variables and methods are special. As end users will directly use public members and methods, priority is given to mantaining consistency of their naming and types. While the protected and private members are implementation deatils that may be more subject to change. +For the same reasons that headers and source files are kept in distinct `include` and `src` directories, this convention is used to make it clear to end users and to implementers that public facing variables and methods are special. As end users will directly use public members and methods, priority is given to maintaining consistency of their naming and types, while the protected and private members are implementation details that may be more subject to change. ~~~ cpp @@ -79,7 +79,7 @@ private: }; ~~~ -Where data members can vary independently those members are simply declared in the public scope and can be set directly, this mirrors Vulkan CreateInfo structs used to set up Vulkan objects, as well as keeping the usage easy to use and the code base clean and minimal. This coherence with Vulkan also means it's easier to reuse Vulkan documentation. If a class only has public scope we simply declare it as a struct. +Where data members can vary independently those members are simply declared in the public scope and can be set directly, this mirrors Vulkan CreateInfo structs used to set up Vulkan objects, as well as keeping the usage simple and the code base clean and minimal. This coherence with Vulkan also means it's easier to reuse Vulkan documentation. If a class only has public scope we simply declare it as a struct. ~~~ cpp struct KeepItSimple @@ -89,7 +89,7 @@ struct KeepItSimple }; ~~~ -For cases where data members have a dependency a protected or private member is used and access is managed through public methods: +For cases where data members have a dependency, a protected or private member is used and access is managed through public methods: ~~~ cpp class AnotherClass diff --git a/1_SettingTheScene/index.md b/1_SettingTheScene/index.md index 974173c..a87e48d 100644 --- a/1_SettingTheScene/index.md +++ b/1_SettingTheScene/index.md @@ -6,7 +6,7 @@ permalink: /SettingTheScene/ **The first draft of this chapter is now complete. We'll make corrections and refine it over the coming weeks** -This chaper introduces developers to the world of Vulkan, Scene Graphs, and how the VulkanSceneGraph combines these technologies to improve productivity and deliver high performance graphics and compute applications, takes you through downloading, building and install software and running the first exercise. The topic is broken down into the following sections: +This chaper introduces developers to the world of Vulkan, Scene Graphs, and how the VulkanSceneGraph combines these technologies to improve productivity and deliver high performance graphics and compute applications, takes you through downloading, building and installing the software and running the first exercise. The topic is broken down into the following sections: 1. [Low-level APIs](LowLevelAPIs.md) 1. [Vulkan](Vulkan.md) diff --git a/2_Foundations/2_PrintVisitor/PrintVisitor.cpp b/2_Foundations/2_PrintVisitor/PrintVisitor.cpp index c935649..c788a03 100644 --- a/2_Foundations/2_PrintVisitor/PrintVisitor.cpp +++ b/2_Foundations/2_PrintVisitor/PrintVisitor.cpp @@ -5,7 +5,7 @@ int main(int, char**) { - // implement simply print visitor that traverses the scene graph printing out node types + // implement simple print visitor that traverses the scene graph printing out node types struct PrintVisitor : public vsg::Inherit { size_t indent = 0; @@ -55,7 +55,7 @@ int main(int, char**) root->addChild(vsg::stringValue::create("Everybody Loves Raymond")); root->addChild(nested); - // consutruct our visitor and then pass it to root node to invoke the visitor. + // construct our visitor and then pass it to root node to invoke the visitor. PrintVisitor print; root->accept(print); diff --git a/2_Foundations/2_observer_ptr/observer_ptr.cpp b/2_Foundations/2_observer_ptr/observer_ptr.cpp index 647c7bf..ca5a754 100644 --- a/2_Foundations/2_observer_ptr/observer_ptr.cpp +++ b/2_Foundations/2_observer_ptr/observer_ptr.cpp @@ -11,19 +11,19 @@ int main(int, char**) std::cout<<" Background thread : has started."<name = "Sun"; - sun->age = 5.603; // 4.603 billion years + sun->age = 5.603; // 5.603 billion years auto earth = astro::Body::create(); earth->name = "Earth"; @@ -37,7 +37,7 @@ int main(int, char**) auto moon = astro::Body::create(); moon->name = "Moon"; - moon->age = 4.51; // 4,51 billion years + moon->age = 4.51; // 4.51 billion years auto mars = astro::Body::create(); mars->name = "Mars"; @@ -51,7 +51,7 @@ int main(int, char**) std::cout<<" pointer = "<; @@ -32,10 +32,10 @@ using PathObjects = std::map>; /// return path stripped of the filename or final path component. extern VSG_DECLSPEC Path filePath(const Path& path); -/// return file extension include the . prefix, i.e. vsg::fileExtension("file.vsgt") returns .vsgt +/// return file extension including the . prefix, i.e. vsg::fileExtension("file.vsgt") returns .vsgt extern VSG_DECLSPEC Path fileExtension(const Path& path); -/// return lower case file extension include the . prefix, i.e. vsg::fileExtension("file.VSGT") returns .vsgt +/// return lower case file extension including the . prefix, i.e. vsg::fileExtension("file.VSGT") returns .vsgt /// By default prunes extras such as REST strings at the end of the extensions, uses ? as the deliminator for REST additions i.e. ".jpeg?g=42" becomes ".jpeg" extern VSG_DECLSPEC Path lowerCaseFileExtension(const Path& path, bool pruneExtras = true); @@ -51,7 +51,7 @@ extern VSG_DECLSPEC Path removeExtension(const Path& path); ## File system functions -The file system functions are grouped together in the [include/vsg/io/FileSystem.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/FileSystem.h#L23) header. The file system functions from this header are: +The file system functions are grouped together in the [include/vsg/io/FileSystem.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/FileSystem.h#L23) header. The file system functions from this header are: ~~~ cpp class Options; @@ -65,7 +65,7 @@ extern VSG_DECLSPEC std::string getEnv(const char* env_var); /// delimiter used is ; under Windows, and : on all other platforms. extern VSG_DECLSPEC Paths getEnvPaths(const char* env_var); -/// parsing multiple environmental variables, parsing them to return a list of Paths. +/// parse multiple environmental variables, merging them to return a list of Paths. template Paths getEnvPaths(const char* env_var, Args... args) { @@ -78,14 +78,14 @@ Paths getEnvPaths(const char* env_var, Args... args) /// return file type, see include/vsg/io/Path.h for FileType enum, extern VSG_DECLSPEC FileType fileType(const Path& path); -/// return true if a specified file/path exist on system. +/// return true if a specified file/path exists on system. extern VSG_DECLSPEC bool fileExists(const Path& path); /// return the full filename path if specified filename can be found in the list of paths. extern VSG_DECLSPEC Path findFile(const Path& filename, const Paths& paths); /// return the full filename path if specified filename can be found in the options->paths list. -/// If options is null and the filename can be found using it's existing path that filename is return, otherwise empty Path{} is returned. +/// If options is null and the filename can be found using its existing path then filename is returned, otherwise empty Path{} is returned. extern VSG_DECLSPEC Path findFile(const Path& filename, const Options* options); /// make a directory, return true if path already exists or full path has been created successfully, return false on failure. @@ -97,7 +97,7 @@ extern VSG_DECLSPEC Paths getDirectoryContents(const Path& directoryName); /// returns the path/filename of the currently executed program. extern VSG_DECLSPEC Path executableFilePath(); -/// Open a file using a the C style fopen() adapted with work with the vsg::Path. +/// Open a file using a the C style fopen() adapted to work with the vsg::Path. extern VSG_DECLSPEC FILE* fopen(const Path& path, const char* mode); ~~~ diff --git a/2_Foundations/MathFunctions.md b/2_Foundations/MathFunctions.md index 05cc15a..bb80fb0 100644 --- a/2_Foundations/MathFunctions.md +++ b/2_Foundations/MathFunctions.md @@ -4,11 +4,84 @@ title: Maths Functions permalink: /foundations/MathsFunctions --- -clamp.h -color.h -common.h -sample.h -transform.h +The VulkanSceneGraph's maths types and functions are found in the [include/vsg/maths](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/) directory. The conventions broadly follow GLSL conventions with additions that are helpful for scene graph usage. In the [Math Types](MathTypes.md) section, earlier in this chapter, the vec2, vec3, vec4, mat3, mat4, quat, plane, box and sphere classes were introduced. In this section we build upon this with a tour of the range of helper functions available and an explanation of the conventions used. + +## Conventions + +The VulkanSceneGraph follows the GLSL convention of [Right Hand Rule](https://en.wikipedia.org/wiki/Right-hand_rule) and [Column Major](https://en.wikipedia.org/wiki/Row-_and_column-major_order) matrices. The GLSL conventions are followed to make it easier to move code between shaders and C++ code, and to make it easier to follow 3rd party coding examples. + +## Headers and associated types/functionality + +| header | types | +| --- | --- | +| *vector and quaternion* | | +| [include/vsg/maths/vec2.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec2.h) | vsg::vec2 | +| [include/vsg/maths/vec3.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec3.h) | vsg::vec3 | +| [include/vsg/maths/vec4.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec4.h) | vsg::vec4 | +| [include/vsg/maths/quat.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/quat.h) | vsg::quat | +| *matrix types* | | +| [include/vsg/maths/mat3.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/mat3.h) | vsg::mat3 | +| [include/vsg/maths/mat4.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/mat4.h) | vsg::mat3 | +| *geometric primitive types* | | +| [include/vsg/maths/plane.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/plane.h) | vsg::plane | +| [include/vsg/maths/sphere.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/sphere.h) | vsg::sphere | +| [include/vsg/maths/box.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/box.h) | vsg::box | +| *functions* | | +| [include/vsg/maths/clamp.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/clamp.h) | clamp and repeat texture coord style functions | +| [include/vsg/maths/color.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/color.h) | color helper functions | +| [include/vsg/maths/common.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/common.h) | angle, square, smoothstep and mix helper functions | +| [include/vsg/maths/sample.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/sample.h) | sample function equvilant to GPU texture sampler | +| [include/vsg/maths/transform.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/transform.h) | range of transform related functions | + +Matrix and vector multiplication: + +~~~ cpp + vsg::dmat4 projection; // typically camera will provide projection matrix + vsg::dmat4 view; // typically camera will provide view matrix + vsg::dmat4 model; // typically transforms in scene graph will be accumulated into model matrix + vsg::dvec3 object_coord; // typically provided by vertices in scene graph + + vsg::dmat4 modelview = view * model; + vsg::dvec3 eye_coord = modelview * object_coord; // implicit transpose of object_coord vector + vsg::dvec3 clip_coord = projection * modelview * object_coord; +~~~ + +Dot and cross products: + +~~~ cpp + vsg::vec3 a(1.0f, 0.0f, 0.0f); + vsg::vec3 b(0.0f, 1.0f, 0.0f); + vsg::vec3 c = vsg::cross(a, b); + float d = vsg::dot(a, b); +~~~ + +Transform related functions: + +~~~ cpp + vsg::dmat4 matrix = vsg::translate(x, y, z) * + vsg::rotate(angle_radians, rx, ry, rz) * + vsg::scale(sx, sy, sz); +~~~ + +## Difference with OpenSceneGraph conventions + +The use of column major contrasts that of the OpenSceneGraph that uses row major, this not only affects order of access for elements of matrices but also the transformation order you'll use. The row major convention used by the OpenSceneGraph was adopted prior to the existence of GLSL which unfortunately chose the opposite convention, leaving the OpenSceneGraph in an awkward situation where C++ and shaders follow differing conventions. + +~~~ cpp +// OpenSceneGraph uses row major +osg::Vec3d osg_vec; +osg::Matrixd osg_matrix; +osg_matrix(row, column) = value; +osg::Vec3d osg_dash = osg_vec * matrix; + +// VulkanSceneGraph using GLSL column major convention +vsg::dvec3 vsg_vec; +vsg::dmat4 vsg_matrix; +vsg_matrix(column, row) = value; +vsg::dvec3 vsg_dask = matrix * vsg_vec +~~~ + +The OpenSceneGraph also implements the dot product and cross product functions as * and ^ operators while the VulkanSceneGraph follows GLSL's convention of using [dot](https://registry.khronos.org/OpenGL-Refpages/gl4/html/dot.xhtml) and [cross](https://registry.khronos.org/OpenGL-Refpages/gl4/html/cross.xhtml) functions. --- diff --git a/2_Foundations/MathTypes.md b/2_Foundations/MathTypes.md index 669eac2..d550925 100644 --- a/2_Foundations/MathTypes.md +++ b/2_Foundations/MathTypes.md @@ -4,11 +4,11 @@ title: Maths Types permalink: /foundations/MathsTypes --- -The VulkanSceneGraph provides GLSL style vector, quaternion and matrix types which are used both to represent data that can be used to store data on the CPU and can be directly mapped to GPU memory for use by shaders, and provides range of standard vector math functions. We'll discuss the [Math Functions](MathFunctions.md) later in this chapter, this page will discuss the data types. +The VulkanSceneGraph provides GLSL style vector, quaternion and matrix types which are used to represent data, they can be used both to store data on the CPU and directly mapped to GPU memory for use by shaders. A range of standard vector [Math Functions](MathFunctions.md) are provided that we'll discuss later in this chapter, this page will discuss the data types. -The math data types are found in the [include/vsg/maths](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/) directory. All the types are declared as template<> structs with definitions provided for the specific types, supporting bool, 8, 16 and 32 bit int and unsigned ints, float and double versions of each type. +The math data types are found in the [include/vsg/maths](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/) directory. All the types are declared as template<> structs with definitions provided for the specific types, supporting bool, 8, 16 and 32 bit int and unsigned ints, float and double versions of each type. -Simple structs are used, only containing the data fields required for the type and are not subclassed from vsg::Object like other scene graph objects as their focus in representing low level data and supporting maths operations. All math types can all be used as part of data objects which we will cover in the next page - [Data Types](DataTypes.md). +Simple structs are used, only containing the data fields required for the type. They are not subclassed from vsg::Object like other scene graph objects as they focus on representing low level data and supporting maths operations. All math types can be used as part of data objects which we will cover in the next page - [Data Types](DataTypes.md). ## Available types and the associated headers @@ -25,7 +25,7 @@ Matrix types: Geometric primitive types: * vsg::plane [include/vsg/maths/plane.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/plane.h) * vsg::sphere [include/vsg/maths/sphere.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/sphere.h) -* vsg::box [include/vsg/maths/sphere.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/box.h) +* vsg::box [include/vsg/maths/box.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/box.h) ## Prefix naming convention @@ -43,7 +43,7 @@ The prefix of the type describes the numerical type, the mappings are: ## Vectors -The [vsg::vec2](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec2.h), [vec3](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec3.h), [vec4](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec4.h) types provide GLSL style access, with {x,y,z,w}, {r,g,b,a}, {s,t,p,q} and [] accessors which all map to the same underlying numerical values. All the vector types also support set(..) methods and assignment. The vector types have a range uses and the accessors used support these: +The [vsg::vec2](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec2.h), [vec3](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec3.h), [vec4](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/maths/vec4.h) types provide GLSL style access, with {x,y,z,w}, {r,g,b,a}, {s,t,p,q} and [] accessors which all map to the same underlying numerical values. All the vector types also support set(..) methods and assignment. The vector types have a range of uses and the accessors used support these: ~~~ cpp // double precision position, good for GIS on CPU @@ -61,16 +61,16 @@ vsg::vec3 normal(0.0f, 0.0f, 1.0f); // floating point vec3 normal.set(0.0f, 1.0f, 0.0f); // colours -vsg::vec4 color(1.0f, 0.0f, 0.0f, 1.0f); // float vec4 representing opqaue red +vsg::vec4 color(1.0f, 0.0f, 0.0f, 1.0f); // float vec4 representing opaque red color.r *= 0.5f; // half the red intensity -color[3] = 1.0f; // set the b channel to 1.0 +color[3] = 1.0f; // set the a channel to 1.0 -vsg::ubvec4 packed_color(0, 255, 0, 127)l // unsigned byte semi-transparent green +vsg::ubvec4 packed_color(0, 255, 0, 127); // unsigned byte semi-transparent green packed_color = vsg::ubvec4(255, 255, 255, 255); // assign an all white color // you can use .x, .r & [0] etc. access interchangeably std::cout<<"color : red = "< poltope = { +std::vector polytope = { {1.0, 0.0, 0.0, 1.0}, // left plane at x=-1, pointing right - {-1.0, 0.0, 0.0, 1.0}, // left plane at x=1, pointing left + {-1.0, 0.0, 0.0, 1.0}, // right plane at x=1, pointing left {0.0, 1.0, 0.0, 1.0}, // front plane at y=-1, pointing forward {0.0, -1.0, 0.0, 1.0}, // back plane at y=1, pointing backward {0.0, 0.0, 1.0, 1.0}, // bottom plane at z=-1, pointing upwards {0.0, 0.0, -1.0, 1.0} // top plane at z=1, pointing downwards }; -// double precision sphere at {10, 20, 30) with radius 40 units +// double precision sphere at {10, 20, 30} with radius of 40 units vsg::dsphere bounding_sphere(10.0, 20.0, 30.0, 40.0); // default constructed single precision box representing an undefined box @@ -144,7 +144,7 @@ vsg::dsphere bounding_sphere(10.0, 20.0, 30.0, 40.0); // when min.x value > max.x then box is treated as undefined/invalid/empty. vsg::box bounding_box; -// use the vsg::box::add(..) method to compute the bounding box that enclosies points +// use the vsg::box::add(..) method to compute the bounding box that encloses points bounding_box.add(vsg::vec3(0.0f, 0.0f, 0.0f)); bounding_box.add(vsg::vec3(10.0f, 0.0f, 0.0f)); bounding_box.add(vsg::vec3(0.0f, 5.0f, 0.0f)); diff --git a/2_Foundations/Metadata.md b/2_Foundations/Metadata.md index fb6f2dc..ac530e8 100644 --- a/2_Foundations/Metadata.md +++ b/2_Foundations/Metadata.md @@ -6,7 +6,7 @@ permalink: /foundations/MetaData ***"data that provides information about other data"*** -The vsg::Object base class has support for Metadata - user named values and objects that can be assigned to and retrieved from objects. Metadata provides an easy way to associate application specific data with scene graph objects without requiring subclassing and extending the scene graph. Serialization support is provided so that all the user assigned values can be stored and retrieved along with the rest of the standard scene graph objects. +The vsg::Object base class has support for Metadata - user named values and objects that can be assigned to and retrieved from objects. Metadata provides an easy way to associate application specific data with scene graph objects without requiring subclassing and extending the scene graph. Serialization support is provided so that all the user assigned values can be stored and retrieved along with the rest of the standard scene graph objects. ## Setting and getting named objects @@ -48,7 +48,7 @@ The foundation of vsg::Object Metadata is a collection of setObject(key, object) void removeObject(const std::string& key); ~~~ -The vsg::Object class implements these methods using a [vsg::Auxiliary](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core/Axuliary.h)) object. vsg::Auxliary object provides both observer_ptr<> support and the std::map> that holds the user assigned objects. The vsg::Auxiliary object is only created and assigned to an vsg::Object when an oberver_ptr<> and/or Metadata are required, as most scene graph objects don't require either; most objects will just have a null Auxliary pointer. +The vsg::Object class implements these methods using a [vsg::Auxiliary](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core/Auxiliary.h) object that provides both observer_ptr<> support and the std::map> that holds the user assigned objects. The vsg::Auxiliary object is only created and assigned to a vsg::Object when an observer_ptr<> and/or Metadata are required. As most scene graph objects don't require either, most objects will just have a null Auxiliary pointer. ## Setting and getting named values @@ -68,7 +68,7 @@ To provide support for standard C++ types like std::string, float and simple sce bool getValue(const std::string& key, T& value) const; ~~~ -These setValue(key, value)/getValue(key) methods build upon the setObject(key, value)/getObject(key) functionality using the vsg::Value<> template data class as an adapter. This adaptation is done for you so users can just focus on the basic types they wish to use. Object::getValue(key, value) return true when the object of the matching Value<> is found in the Auxiliary::usersObjects map, otherwise it returns false. It is important to exactly match the types between setValue(key, value) and getValue(key, value) as no implicit type conversion is supported, i.e. setting with a float then attempting to get with a double will not find a match and return false. +These setValue(key, value)/getValue(key) methods build upon the setObject(key, value)/getObject(key) functionality using the vsg::Value<> template data class as an adapter. This adaptation is done for users so they can just focus on the basic types they wish to use. Object::getValue(key, value) returns true when the object of the matching Value<> is found in the Auxiliary::userObjects map, otherwise it returns false. It is important to exactly match the types between setValue(key, value) and getValue(key, value) as no implicit type conversion is supported, i.e. setting with a float then attempting to get with a double will not find a match and return false. ~~~ cpp { @@ -98,7 +98,7 @@ These setValue(key, value)/getValue(key) methods build upon the setObject(key, v } ~~~ -As the Object::setValue(key, value), getValue(key, value) functionality is built upon vsg::Value so you can also get the value object: +As the Object::setValue(key, value), getValue(key, value) functionality is built upon vsg::Value, you can also get the value object: ~~~ cpp // you can get the underlying object using the same key: @@ -119,7 +119,7 @@ The vsg::Auxiliary object assigned to a vsg::Object, in order to provide meta da ~~~ cpp auto object = vsg::Object::create(); -object->setValue("name", "Adrian Mole" +object->setValue("name", "Adrian Mole"); object->setValue("age", 13.75); if (auto auxiliary = object->getAuxiliary()) @@ -139,4 +139,4 @@ else In the next section we'll discover other ways of determining the type of objects which avoid the need to use the awkward and costly dynamic_cast<> between types. -Prev: Next: [Data Types](DataTypes.md)| Next: [Run Time Time Identification (RTTI)](RTTI.md) +Prev: Next: [Data Types](DataTypes.md)| Next: [Run-Time Type Information (RTTI)](RTTI.md) diff --git a/2_Foundations/Object_base_class_and_ref_ptr.md b/2_Foundations/Object_base_class_and_ref_ptr.md index 3fe5a8d..e004108 100644 --- a/2_Foundations/Object_base_class_and_ref_ptr.md +++ b/2_Foundations/Object_base_class_and_ref_ptr.md @@ -4,17 +4,17 @@ title: vsg::ref_ptr<> & vsg::Object base class permalink: /foundations/BaseClassesAndSmartPointers --- -To provide robust, thread-safe, high performance memory manangment the VulkanSceneGraph uses intrusive reference counting and block memory allocation. The three main classes that provide this functionality are vsg::Object base class, the vsg::ref_ptr<> smart pointer and vsg::Allocator singleton. The vsg::Auxiliary class and vsg::observer_ptr<> smart pointer provide additional meta data and weak pointer functionality. In this section we'll convert the vsg::Object base class and the vsg::ref_ptr<> smart pointer and then cover the vsg::Auxiliary, observer_ptr<> and vsg::Allocator in the following two sections. +To provide robust, thread-safe, high performance memory management the VulkanSceneGraph uses intrusive reference counting and block memory allocation. The three main classes that provide this functionality are the vsg::Object base class, the vsg::ref_ptr<> smart pointer class and the vsg::Allocator singleton. The vsg::Auxiliary class and vsg::observer_ptr<> smart pointer provide additional meta data and weak pointer functionality. In this section we'll cover the vsg::Object base class and the vsg::ref_ptr<> smart pointer and then cover the vsg::Auxiliary, vsg::observer_ptr<> and vsg::Allocator in the following two sections. -## Intrusive vs non-instrusive reference counting +## Intrusive vs non-intrusive reference counting Reference counting is widely used in applications to facilitate robust sharing of objects allocated on the heap. The two main approaches used in C++ applications are intrusive and non-intrusive reference counting, each have strengths and weaknesses. -Standard C++ provides the std::shared_ptr<> smart pointer that uses non-instrusive counting. The design requires the shared_ptr<> to hold two pointers, one to the object being managed and one to a shared reference count. The advantage of non intrusive reference counting is that it can be used with all types, from bool to std::vector to user classes. The disadvantage of the shared_ptr<> is twice the size of a C pointer which has singinficant performance consequences which we'll discuss in detail below. +Standard C++ provides the std::shared_ptr<> smart pointer that uses non-intrusive counting. The design requires the shared_ptr<> to hold two pointers, one to the object being managed and one to a shared reference count. The advantage of non intrusive reference counting is that it can be used with all types, from bool to std::vector to user classes. The disadvantage of the shared_ptr<> is that it's twice the size of a C pointer which has significant performance consequences which we'll discuss in detail below. -With intrusive reference counting the count is placed into the object, in the case of the VulkanSceneGraph is this is provided by the vsg::Object base classes atomic _referneceCount member variable which is accessed via the ref() and unref() methods that increment and decrement the count and when the count goes to zero the object is automatically deleted. To ensure that the ref() and unref() methods are called consistently the vsg::ref_ptr<> smart pointer is provided, similar in role to the std::shared_ptr<>, but having the advantage that it only requires a single C pointer so is the same size as a C pointer, and half the memory footprint of the std::shared_ptr<>. The disadvantage with intrusive reference counting is that you can not use it directly with types like bool etc. +With intrusive reference counting the count is placed into the object, in the case of the VulkanSceneGraph this is provided by the vsg::Object base classes atomic _referenceCount member variable which is accessed via the ref() and unref() methods that increment and decrement the count and when the count goes to zero the object is automatically deleted. To ensure that the ref() and unref() methods are called consistently the vsg::ref_ptr<> smart pointer is provided, similar in role to the std::shared_ptr<>, but having the advantage that it only requires a single C pointer so is the same size as a C pointer, and half the memory footprint of the std::shared_ptr<>. The disadvantage with intrusive reference counting is that you can not use it directly with types like bool etc. -For the case of a scene graph we have a data structure where the internal nodes of the graph are primarily pointers to data objects or other nodes in the scene graph, if you double the size of the pointer you almost double the size of internal nodes in the graph. Increasing the size of the nodes means you require more memory and crucially can fit less nodes into cache which means more cache misses and lower CPU utilization. Benchmarking done comparing the traversal speeds of scene graph uses std::shared_ptr<> vs one with vsg::ref_ptr<> show that the intrusive reference counted scene graph is 15% faster. +For the case of a scene graph we have a data structure where the internal nodes of the graph are primarily pointers to data objects or other nodes in the scene graph, if you double the size of the pointer you almost double the size of internal nodes in the graph. Increasing the size of the nodes means you require more memory and crucially can fit less nodes into cache which means more cache misses and lower CPU utilization. Benchmarking done comparing the traversal speeds of a scene graph using std::shared_ptr<> vs one with vsg::ref_ptr<> shows that the intrusive reference counted scene graph is 15% faster. ## Creating objects and smart pointers @@ -29,11 +29,11 @@ struct MyClass double value = 0.0; }; -// allocate a MyClass object on the heap and assigns to std::shared_ptr +// allocates a MyClass object on the heap and assigns to std::shared_ptr auto ptr = std::make_shared("fred"); ~~~ -While the equivalent with the VulkanSceneGraph requires MyClass to be subclass from vsg::Object to add the itrusive reference counting: +The equivalent with the VulkanSceneGraph requires MyClass to be subclassed from vsg::Object to add the intrusive reference counting: ~~~ cpp struct MyClass : public vsg::Object @@ -44,13 +44,13 @@ struct MyClass : public vsg::Object double value = 0.0; }; -// allocate a MyClass object on the heap and assigns to vsg::ref_ptr +// allocates a MyClass object on the heap and assigns to vsg::ref_ptr vsg::ref_ptr ptr(new MyClass("ginger")); ~~~ -The VulkanSceneGraph has another feature that makes it even cleaner to allocate objects robustly and add RTTI features - the vsg::Inherit<> template class. vsg::Inherit is an example the [Curiously Recurring Template Pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), while a somewhat non-intuitive idiom it neatly solves a problem of how to implement class specific extensions to a base class in consistent and robust way. +The VulkanSceneGraph has another feature that makes it even cleaner to allocate objects robustly and add RTTI features - the vsg::Inherit<> template class. vsg::Inherit is an example of the [Curiously Recurring Template Pattern](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), while a somewhat non-intuitive idiom it neatly solves a problem of how to implement class specific extensions to a base class in a consistent and robust way. -We'll cover more of these features of vsg::Object and vsg::Inherit later in the tutorial, for now we'll just focus on the benefits for conveniently allocating objects. With the following revised code we leverage the create() method provided by vsg::Inerhit<> that allocates the memory and calls the constructor of the object using the parameters you pass to create(..) and returns a vsg::ref_ptr<> of the appropriate type. Usage is simply: +We'll cover more of these features of vsg::Object and vsg::Inherit later in the tutorial, for now we'll just focus on the benefits for conveniently allocating objects. With the following revised code we leverage the create() method provided by vsg::Inherit<> that allocates the memory and calls the constructor of the object using the parameters you pass to create(..) and returns a vsg::ref_ptr<> of the appropriate type. Usage is simply: ~~~ cpp struct MyClass : public vsg::Inherit @@ -61,15 +61,15 @@ struct MyClass : public vsg::Inherit double value = 0.0; }; -// allocate a MyClass object on the heap, using vsg::Allocator, and assigns to vsg::ref_ptr +// allocates a MyClass object on the heap, using vsg::Allocator, and assigns to vsg::ref_ptr auto ptr = MyClass::create("ginger"); ~~~ -While the declaration of the MyClass is a little more complicated the benefit is cleaner and more expressive object creation syntax, that requires less code to type than either of the ref_ptr(new T()) and std::make_shared() usage. The use of the T::create(..) method is used throughout the VulkanSceneGraph codebase - it doesn't just make it more convenient for end users, it makes life easier for the developers of software as well. +While the declaration of the MyClass is a little more complicated the benefit is cleaner and more expressive object creation syntax, that requires less code to type than either of the ref_ptr(new T()) and std::make_shared() usage. The use of the T::create(..) method is used throughout the VulkanSceneGraph codebase - it doesn't just make it more convenient for end users, it makes life easier for the developers of software as well. ## The strengths of smart pointers -The main reason for smart pointers is to make it easier to develop robust applications, and in the case of the vsg::ref_ptr<>/vsg:::Object combination there is no memory or performance overhead over using C pointers except for specific usage cases. The following are a few examples of how smart_pointers leads to cleaner and more robust code. +The main reason for smart pointers is to make it easier to develop robust applications, and in the case of the vsg::ref_ptr<>/vsg::Object combination there is no memory or performance overhead over using C pointers except for specific usage cases. The following are a few examples of how smart pointers lead to cleaner and more robust code. Addressing memory leaks: @@ -94,23 +94,23 @@ Addressing memory leaks: // do the processing we want // - c_ptr->unref(); // decrement refenreceCount to 0 and delete MyClass + c_ptr->unref(); // decrement referenceCount to 0 and delete MyClass } // 3. Using ref_ptr<> { - auto ptr = MyClass::create(); // allocate MyClass on heap, assign to ref_ptr which increments it's referenceCount. + auto ptr = MyClass::create(); // allocate MyClass on heap, assign to ref_ptr which increments its referenceCount. // // do the processing we want // -} // when ptr destructs it automatically decrements it's referenceCount which hits 0 and leads to the object being deleted. +} // when ptr destructs it automatically decrements its referenceCount which hits 0 and leads to the object being deleted. ~~~ -Cases 1 & 2 are fine as long as the code blocks never exit prematurely, but what happens if there is a an early return or an exception thrown in the processing section? It will leak the object allocated on the heap. With case 3 using ref_ptr<> an early return from the block will always invoke the ref_ptr<> destructor and always clean up the memory associated with it - the code isn't just simpler it's far more robust as well. +Cases 1 & 2 are fine as long as the code blocks never exit prematurely, but what happens if there is an early return or an exception thrown in the processing section? It will leak the object allocated on the heap. With case 3 using ref_ptr<> an early return from the block will always invoke the ref_ptr<> destructor and always clean up the memory associated with it - the code isn't just simpler it's far more robust as well. -Referencing counting also helps when passing back objects out from the scope of a code block: +Reference counting also helps when passing back objects out from the scope of a code block: ~~~ cpp // 4. Using C pointers can lead to dangling pointers @@ -125,7 +125,7 @@ MyClass* other_ptr = nullptr; // take a copy of the pointer other_ptr = c_ptr; - delete c_ptr; // explicitly delete object cleans up memory but causes a dangling pointer + delete c_ptr; // explicitly delete object, cleans up memory but causes a dangling pointer } other_ptr->value = 10.0; // seg fault as the object has already been deleted @@ -142,27 +142,27 @@ MyClass* other_ptr = nullptr; other_ptr = c_ptr; other_ptr->ref(); // increment referenceCount to 2 - c_ptr->unref(); // decrement refenreceCount to 1 so no deletion! + c_ptr->unref(); // decrement referenceCount to 1 so no deletion! } other_ptr->value = 10.0; // assignment safe as object is still on the heap -other_ptr->unref(); // decrement refenreceCount to 0 and delete MyClass +other_ptr->unref(); // decrement referenceCount to 0 and delete MyClass // 6. Using ref_ptr<> vsg::ref_ptr other_ptr; { - auto ptr = MyClass::create(); // allocate MyClass on heap, assign to ref_ptr which increments it's referenceCount to 1. + auto ptr = MyClass::create(); // allocate MyClass on heap, assign to ref_ptr which increments its referenceCount to 1. // // do the processing we want // - other_ptr = ptr; // smart pointer assignment automatically increasments reference count to 2 + other_ptr = ptr; // smart pointer assignment automatically increases reference count to 2 -} // when ptr destructs it automatically decrements it's referenceCount which hits 1, no deletion! +} // when ptr destructs it automatically decrements its referenceCount which hits 1, no deletion! other_ptr->value = 10.0; // assignment safe as object is still on the heap ~~~ -In case 4 it is possible to fix the seg fault by moving the delete to after the last time that other_ptr is used, however if the processing section returns early or throws an exception the memory will be lost. Case 5 will work correctly as long as the processing section doesn't return early or throws an exception in which case it will leak the allocation object. Again case 6 is both cleaner and handles the early return case correctly, cleaning up any objects that have been allocated and no longer have an external reference. +In case 4 it is possible to fix the seg fault by moving the delete to after the last use of other_ptr, however if the processing section returns early or throws an exception the memory will leak. Case 5 will work correctly as long as the processing section doesn't return early or throws an exception in which case it will leak the allocated object. Again case 6 is both cleaner and handles the early return case correctly, cleaning up any objects that have been allocated and no longer have an external reference. These examples illustrate why smart pointers are so useful and why you'll find them used throughout the VulkanSceneGraph codebase and applications that use it: 1. Less code to write @@ -171,7 +171,7 @@ These examples illustrate why smart pointers are so useful and why you'll find t ## Don't mix delete, std::shared_ptr<> & std::ref_ptr<> -The code examples above implement MyClass by subclassing from vsg::Inherit<> makes it possible to seamlessly use MyClass::create() and ref_ptr<>, but it possible also to write and compile code that still uses std::shared_ptr<> we strongly recommend against doing so as you create a situation where there two independent reference counting mechanisms attempt to manage a single object. +The code examples above implement MyClass by subclassing from vsg::Inherit<> which makes it possible to seamlessly use MyClass::create() and ref_ptr<>, but it's possible also to write and compile code that still uses std::shared_ptr<>. We strongly recommend against doing so as you create a situation where there are two independent reference counting mechanisms attempting to manage a single object. ~~~ cpp struct MyClass : public vsg::Inherit @@ -183,10 +183,10 @@ struct MyClass : public vsg::Inherit auto vsg_ptr = MyClass::create("carrie"); -// will compile but create dangling pointers once either vsg_ptr and std_ptr go out of scope +// will compile but create dangling pointers once either vsg_ptr or std_ptr goes out of scope std::shared_ptr std_ptr(vsg_ptr.ptr()); -// we could even just delete the object directly and mess up both vsg_ptr std_ptr. +// we could even just delete the object directly and mess up both vsg_ptr and std_ptr. delete vsg_ptr.get(); ~~~ @@ -212,11 +212,11 @@ std::shared_ptr std_ptr(vsg_ptr.ptr()); delete vsg_ptr.get(); ~~~ -The VulkanSceneGraph uses this pattern throughout the codebase so when you see the destructor declared in protected or private section of the class you know that that instances of that class are meant to be only declared on the heap and meant to be used with vsg::ref_ptr<>. The T::create() support provided by vsg::Inherit<> achieves both these requirements. +The VulkanSceneGraph uses this pattern throughout the codebase so when you see the destructor declared in the protected or private section of the class you know that instances of that class are meant to be only declared on the heap and meant to be used with vsg::ref_ptr<>. The T::create() support provided by vsg::Inherit<> achieves both these requirements. ## Don't mix stack allocation and reference counting -Another potential issue when using smart pointers and reference counting is when objects are allocated on the stack rather than on the heap. Stack allocation happens automatically for variables within a scope and all the allocated objects are automatically destructed at the end of the scope. The examples using std::shared_ptr<> and vsg::ref_ptr<> leverage this behavior, using the destruction of the smart pointers to unreference the objects they have shared ownership of. The problem occurs if user allocate objects on the stack and then attempt to reference count them as well. The following example illustrates this: +Another potential issue when using smart pointers and reference counting is when objects are allocated on the stack rather than on the heap. Stack allocation happens automatically for variables within a scope and all the allocated objects are automatically destructed at the end of the scope. The examples using std::shared_ptr<> and vsg::ref_ptr<> leverage this behavior, using the destruction of the smart pointers to unreference the objects they have shared ownership of. The problem occurs if a user allocates objects on the stack and then attempts to reference count them as well. The following example illustrates this: ~~~ cpp @@ -232,15 +232,14 @@ vsg::ref_ptr ptr; { MyClass object("carrie"); // object created on the stack in local scope - // assign okect to the ref_ptr<> that increments it's ref count to 1. + // assign object to the ref_ptr<> that increments its ref count to 1. ptr = &object; } // object is destructed automatically because it was allocated on stack, it doesn't matter what the ref count is. -ptr->value += 10.0; // seg fault as object was deleted on exiting it's scope +ptr->value += 10.0; // seg fault as object was deleted on exiting its scope ~~~ -This same issue occurs for std::shared_ptr<>, you simply can't prevent the destruction of objects on the stack. If you want to manage your objects using smart pointer you must only use them with objects allocated on the heap. Thankfully the same technique of declaring the destructor protected/private prevent compilation of the code works for prevent stack construction as it does for prevent use with shared_ptr<> and explicitly deleting an object. - +This same issue occurs for std::shared_ptr<>, you simply can't prevent the destruction of objects on the stack. If you want to manage your objects using smart pointers you must only use them with objects allocated on the heap. Thankfully the same technique of declaring the destructor protected/private that works to prevent use with shared_ptr<> and explicitly deleting an object works to prevent stack construction as well. ~~~ cpp class MyClass : public vsg::Inherit { @@ -258,7 +257,7 @@ protected: } ~~~ -Most classes in the VulkanSceneGraph are declared with a protected destructor to prevent this problem usage, but there a couple of classes like subclasses from vsg::Visitor that for convenience and efficiency may be fine to allocate on the stack and let the automatic destruction clean up the objects without needing to allocate on the heap and use smart pointers. For these special cases developers may decide to not declare a protected destructor, but they should be wary of this potential pitfalls in doing this. Later in this chapter we will discuss vsitors classes in detail and touch upon the time when stack vs heap allocation will be preferable. +Most classes in the VulkanSceneGraph are declared with a protected destructor to prevent this problem usage, but there are a couple of classes like subclasses from vsg::Visitor that for convenience and efficiency may be fine to allocate on the stack and let the automatic destruction clean up the objects without needing to allocate on the heap and use smart pointers. For these special cases developers may decide to not declare a protected destructor, but they should be wary of the potential pitfalls in doing this. Later in this chapter we will discuss visitor classes in detail and touch upon the time when stack vs heap allocation will be preferable. Prev: [Foundations](index.md)| Next: [vsg::observer_ptr<>](observer_ptr.md) diff --git a/2_Foundations/RTTI.md b/2_Foundations/RTTI.md index b9796f2..4733372 100644 --- a/2_Foundations/RTTI.md +++ b/2_Foundations/RTTI.md @@ -1,12 +1,12 @@ --- layout: page -title: Run Time Type Identification (RTTI) +title: Run-Time Type Information (RTTI) permalink: /foundations/RTTI --- -The VulkanSceneGraph provides a number of features that provide richer and more efficient Run Time Type Information (RTTI) and type safe operations than are provided by C++ itself. These features are provided by the vsg::Object base class and by two companion bass classes, the vsg::Visitor and vsg::ConstVisitor, with the vsg::Inherit CRTP class providing convenient implementations of the required methods. In this section we'll focus on the RTTI features provided by vsg::Object/vsg::Inherit. +The VulkanSceneGraph provides a number of features that provide richer and more efficient RunTime Type Information (RTTI) and type safe operations than are provided by C++ itself. These features are provided by the vsg::Object base class and by two companion base classes, the vsg::Visitor and vsg::ConstVisitor, with the vsg::Inherit CRTP class providing convenient implementations of the required methods. In this section we'll focus on the RTTI features provided by vsg::Object/vsg::Inherit. -## RTTI features provided vsg::Object +## RTTI features provided by vsg::Object The vsg::Object base class provides the following methods dedicated to RTTI: @@ -27,15 +27,16 @@ const T* cast() const { return is_compatible(typeid(T)) ? static_cast( virtual int compare(const Object& rhs) const; ~~~ -The vsg::Object::className() method is implemented using the vsg::type_name<> template function, specializations of vsg::type_name<> are in turn provided by the VSG_type_name() and EVSG_type_name() macro functions that can be placed before/after a class definition, both of these features are defined in [include/vsg/core/value_type.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/type_name.h). The VSG_type_name() macro can be used for classes within the vsg namespace like [vsg::Group](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/group.h). While the EVSG_type_name() version can be used for classes defined in other namespaces, such as what you see in [vsgXchange](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/all.h#L43). +The vsg::Object::className() method is implemented using the vsg::type_name<> template function, specializations of vsg::type_name<> are in turn provided by the VSG_type_name() and EVSG_type_name() macro functions that can be placed before/after a class definition, both of these features are defined in [include/vsg/core/value_type.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/type_name.h). The VSG_type_name() macro can be used for classes within the vsg namespace like [vsg::Group](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/group.h), while the EVSG_type_name() version can be used for classes defined in other namespaces, such as what you see in [vsgXchange](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/all.h#L43). -The vsg::Object::type_info() method provides a convenient way to access the std::type_info of a particular object, and vsg::Object::is_compatible(const std::type_info&) method provides a method that can not just check whether a type is the same, but whether it may be derived from that type and thus compatible with treatment as that type. The vsg::Inherit<> class can be used to automatically implement the required type_info() and is_compatible() methods. +The vsg::Object::type_info() method provides a convenient way to access the std::type_info of a particular object, and vsg::Object::is_compatible(const std::type_info&) method provides a method that can not just check whether a type is the same, but whether it may be derived from that type and thus compatible with treatment as that type. The vsg::Inherit<> class can be used to automatically implement the required type_info() and is_compatible() methods. The vsg::Object::cast<>() template methods use the Object::is_compatible() method to decide whether one can directly cast to a desired type using static_cast<> without the high CPU overhead of invoking dynamic_cast<>. -The vsg::Object::compare(..) method provides a way of comparing two objects, both for type and the contents of the object. The int std::memcmp(..) convention is used, with negative for AB. The vsg::Inherit<> class provides a very basic compare(..) implementation but it's recommend to implement this locally for any class that holds anything more than simple types. The [include/vsg/core/compare.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/compare.h) header provides a range of convenience template functions to make the task easier. +The vsg::Object::compare(..) method provides a way of comparing two objects, both the type and the contents of the object. The int std::memcmp(..) convention is used, with negative for AB. The vsg::Inherit<> class provides a very basic compare(..) implementation but it's recommended to implement this locally for any class that holds anything more than simple types. The [include/vsg/core/compare.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/compare.h) header provides a range of convenience template functions to make the task easier. + +To illustrate these features, with the [RTTI example](https://github.com/vsg-dev/vsgTutorial/blob/master/2_Foundations/2_rtti/), we'll declare a custom class in its own namespace and use Inherit to implement the RTTI methods, EVSG_type_name to provide the human readable naming and implement the compare() method. -To illustrate these features, with the [RTTI example](https://github.com/vsg-dev/vsgTutorial/blob/master/2_Foundations/2_rtti/) example, we'll declare a custom class in it's own namespace and use Inherit to implement the RTTI methods, EVSG_type_name to provide the human readable naming and the implement compare() method. ~~~ cpp namespace astro { @@ -66,7 +67,7 @@ We can then use this functionality in application code, first we create our main // second constructed body object auto sun = astro::Body::create(); sun->name = "Sun"; - sun->age = 5.603; // 4.603 billion years + sun->age = 5.603; // 5.603 billion years auto earth = astro::Body::create(); earth->name = "Earth"; @@ -74,7 +75,7 @@ We can then use this functionality in application code, first we create our main auto moon = astro::Body::create(); moon->name = "Moon"; - moon->age = 4.51; // 4,51 billion years + moon->age = 4.51; // 4.51 billion years auto mars = astro::Body::create(); mars->name = "Mars"; @@ -101,7 +102,7 @@ Bodies before sorting To test out RTTI support we'll assign the body objects to a more generic vector>, assign some extra vsg::Object instances, and then leveraging the compare() functionality sort the vector and print out the results: ~~~ cpp - // copy the bodies container over to a more generic objects containers, + // copy the bodies container over to a more generic objects container, // to illustrate how subclassing still works with more generic types std::vector> objects(bodies.begin(), bodies.end()); @@ -121,7 +122,7 @@ To test out RTTI support we'll assign the body objects to a more generic vector< for(auto& object : objects) { // to access the specific Body member variables we need to cast from ref_ptr to ref_ptr - // ref_ptr<>.cast() is implemented using th vsg::Object::cast<>() to efficiently replace a dynamic_cast<>. + // ref_ptr<>.cast() is implemented using the vsg::Object::cast<>() to efficiently replace a dynamic_cast<>. if (auto body = object.cast()) { std::cout<<" pointer = "< to cast to specific type and ref_ptr pointer @@ -29,7 +27,7 @@ auto data = vsg::read_cast("image.vsgt"); auto vertexShader = vsg::read_cast("shader.vert"); ~~~ -Write function are found in [include/vsg/io/write.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/write.h), usage is in form: +Write functions are found in [include/vsg/io/write.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/write.h), usage is in the form of: ~~~ cpp // create an object @@ -41,7 +39,7 @@ vsg::write(value, "value.vsgt"); ## Options & vsgXchange intro -Customization and extension of reading and writing is provided by the [vsg::Options](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/Options.h) object that can be passed to the vsg;:read(..) and vsg::write(..) methods. You can pass in the ReaderWriters that you wish to use, placing them in the order you want them invoked. vsg::Options is subclassed from vsg::Object so has all the standard meta data capabilities and adds IO specific settings. The most common task will be passing in the paths to search for files, and the ReaderWriters to check, such as adding in support for the ReaderWriter's provided by vsgXchange. The usage pattern is: +Customization and extension of reading and writing is provided by the [vsg::Options](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/Options.h) object that can be passed to the vsg::read(..) and vsg::write(..) methods. You can pass in the ReaderWriters that you wish to use, placing them in the order you want them invoked. vsg::Options is subclassed from vsg::Object so has all the standard meta data capabilities and adds IO specific settings. The most common task will be passing in the paths to search for files, and the ReaderWriters to check, such as adding in support for the ReaderWriters provided by vsgXchange. The usage pattern is: ~~~ cpp #include @@ -55,7 +53,7 @@ int main(int, char**) // set up the paths options->paths = vsg::getEnvPaths("VSG_FILE_PATH"); - // assign the ReaderWriter's to use when read/writing + // assign the ReaderWriters to use when read/writing options->add(vsgXchange::all::create()); // load GLTF model using vsgXchange::assimp that is included in vsgXchange::all, passing in options so read knows what to use @@ -98,8 +96,8 @@ public: /// Hint to use when searching for Paths with vsg::findFile(filename, options); enum FindFileHint { - CHECK_ORIGINAL_FILENAME_EXISTS_FIRST, /// check the filename exists with it's original path before trying to find it in Options::paths. - CHECK_ORIGINAL_FILENAME_EXISTS_LAST, /// check the filename exists with it's original path after failing to find it in Options::paths. + CHECK_ORIGINAL_FILENAME_EXISTS_FIRST, /// check the filename exists with its original path before trying to find it in Options::paths. + CHECK_ORIGINAL_FILENAME_EXISTS_LAST, /// check the filename exists with its original path after failing to find it in Options::paths. ONLY_CHECK_PATHS /// only check the filename exists in the Options::paths }; FindFileHint checkFilenameHint = CHECK_ORIGINAL_FILENAME_EXISTS_FIRST; @@ -120,7 +118,7 @@ public: /// Coordinate convention to assume for specified lower case file formats extensions std::map formatCoordinateConventions; - /// User defined ShaderSet map, loaders should check the available ShaderSet used the name of the type ShaderSet. + /// User defined ShaderSet map, loaders should check the available ShaderSet using the name of the type of ShaderSet. /// Standard names are : /// "pbr" will substitute for vsg::createPhysicsBasedRenderingShaderSet() /// "phong" will substitute for vsg::createPhongShaderSet() @@ -134,15 +132,16 @@ protected: VSG_type_name(vsg::Options); ~~~ -In later chapters we'll revist the features of vsg::Options in more depth. +In later chapters we'll revisit the features of vsg::Options in more depth. ## ReaderWriter -The vsg::ReaderWriter base class provides the mechanism for implementing support for both native and 3rd party file formats. The [Chain of Responsibility Design Pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) is used with each ReaderWriter implementation taking responsibility for whether it can handle reading from or writing to a file or strean. The ReaderWriter's are invoked by the vsg::read(..)/vsg::write() calls in the order that they appear in the vsg::Options::readerWriters list, and if none can handle the read/write then the built in ReaderWriter's are called as fallback. +The vsg::ReaderWriter base class provides the mechanism for implementing support for both native and 3rd party file formats. The [Chain of Responsibility Design Pattern](https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern) is used with each ReaderWriter implementation taking responsibility for whether it can handle reading from or writing to a file or stream. The ReaderWriters are invoked by the vsg::read(..)/vsg::write() calls in the order that they appear in the vsg::Options::readerWriters list, and if none can handle the read/write then the built in ReaderWriters are called as fallback. + +There are three types of each of the virtual ReaderWriter::read(..) methods that take filename, istream or a block of memory as the source to read, and two types of virtual ReaderWrite::write(..) methods that take a filename or ostream to write to. A virtual ReaderWriter::getFeatures(..) method provides a way to reporting to applications whether read/write features are supported. The full public interface to [ReaderWriter](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/ReaderWriter.h#L33) is: -There are three types of each of virtual RaderWriter::read(..) methods that take filename, istream or block of memory as the source to read, and two type of virtual ReaderWrite::write(..) methods that take a filename or ostream to write to. A virtual ReaderWrier::getFeatures(..) method provides a way to reporting to applications that read/write features are supported. The full public interface to [ReaderWriter](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/ReaderWriter.h#L33) is: ~~~ cpp -/// Base class from providing support for reading and/or writing various file formats and IO protocols +/// Base class for providing support for reading and/or writing various file formats and IO protocols class VSG_DECLSPEC ReaderWriter : public Inherit { public: diff --git a/2_Foundations/Serialization.md b/2_Foundations/Serialization.md index d95305d..d70e30d 100644 --- a/2_Foundations/Serialization.md +++ b/2_Foundations/Serialization.md @@ -1,21 +1,21 @@ --- layout: page -title: Serializaton +title: Serialization permalink: /foundations/Serializaton --- -The VulkanSceneGraph provides extensible serialization support so that all scene graph objects can be read/written from files and streams. This can be used with the native .vsgb binary and .vsgt ascii formats as well work with users defined input/output through to reading data compiled directly into example as illustrated in the use of the vsgXchange::cpp ReaderWriter in the previous section on vsgXchange. +The VulkanSceneGraph provides extensible serialization support so that all scene graph objects can be read from/written to files and streams. This can be used with the native .vsgb binary and .vsgt ascii formats as well as work with user defined input/output through to reading data compiled directly into applications as illustrated in the use of the vsgXchange::cpp ReaderWriter in the previous section on vsgXchange. ## vsg::Object, Input and Output base classes -The serializtion support is built upon vsg::Object base class that provides virtual read(Input&) and write(Output&) methods that users override to implement support for their own member variables, and the vsg::Input and vsg::Output classes that provide a standarizaed interface for reading and writing data. The [vsg::Object](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core/Object.h#L88) methods are: +The serialization support is built upon the vsg::Object base class that provides virtual read(Input&) and write(Output&) methods that users override to implement support for their own member variables, and the vsg::Input and vsg::Output classes that provide a standardized interface for reading and writing data. The [vsg::Object](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/core/Object.h#L88) serialization methods are: ~~~ cpp virtual void read(Input& input); virtual void write(Output& output) const; ~~~ -The [vsg::Input](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Input.h#L37) base class provides the low level pure virtual methods that are implemented by the concrete implementation of Input like vsg::BinaryInput and vsg::AsciiInput as well as set of template methods that meant to be used by the read(Input&) methods to implement the serialization of class members. The later methods take the form of input.read(proptertyName, value): +The [vsg::Input](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Input.h#L37) base class provides the low level pure virtual methods that are implemented by the concrete implementations of Input like vsg::BinaryInput and vsg::AsciiInput as well as a set of template methods that are meant to be used by the read(Input&) methods to implement the serialization of class members. The latter methods take the form of input.read(propertyName, value): ~~~ cpp /// treat non standard type as raw data, @@ -50,12 +50,12 @@ void readObject(const char* propertyName, ref_ptr& arg); template T readValue(const char* propertyName); -/// read a value as a type, then cast it another type +/// read a value as a type, then cast it to another type template void readValue(const char* propertyName, T& value); ~~~ -The [vsg::Output](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Output.h#L37) base class methods mirror those in vsg::Input, providing the pure virtual methods that are used to implement the low serialization, and then higher level user facing methods that are used by end users, the later take the form output.write(property, value): +The [vsg::Output](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Output.h#L37) base class methods mirror those in vsg::Input, providing the pure virtual methods that are used to implement the low level serialization, and then higher level user facing methods that are used by end users, the latter take the form output.write(property, value): ~~~ cpp template @@ -70,13 +70,13 @@ void writeValues(const char* propertyName, const std::vector& values); template void writeValues(const char* propertyName, const std::set& values); -/// match propertyname and write value(s) +/// match propertyName and write value(s) template void write(const char* propertyName, Args&... args); void writeObject(const char* propertyName, const Object* object); -/// write a value casting it specified type i.e. output.write("Value", value); +/// write a value casting it to specified type i.e. output.write("Value", value); template void writeValue(const char* propertyName, T value); ~~~ @@ -84,15 +84,15 @@ void writeValue(const char* propertyName, T value); ## vsg::ObjectFactory -When writing out objects you can simply call **object->write(output)** and the appropriate serialization will be invoked, but when you need to serialize back in a file the appropriate objects have to be created then their **object->read(input)** method can be invoked to read the object members. The way the VulkanSceneGraph provides a means for creating objects on demand is via the [vsg::ObjectFactory](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/ObjectFactory.h#L24) singleton class, where only one instance of the Factory exists. The vsg::ObjectFactory is an example of [Factory Method Design Pattern](https://en.wikipedia.org/wiki/Factory_method_pattern) and [Singleton Design Pattern](https://en.wikipedia.org/wiki/Singleton_pattern). +When writing out objects you can simply call **object->write(output)** and the appropriate serialization will be invoked, but when you need to serialize a file back in, the appropriate objects have to be created before their **object->read(input)** method can be invoked to read the object members. The way the VulkanSceneGraph provides a means for creating objects on demand is via the [vsg::ObjectFactory](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/ObjectFactory.h#L24) singleton class, where only one instance of the Factory exists. The vsg::ObjectFactory is an example of the [Factory Method Design Pattern](https://en.wikipedia.org/wiki/Factory_method_pattern) and [Singleton Design Pattern](https://en.wikipedia.org/wiki/Singleton_pattern). -The core scene graph classes found in the VulkanSceneGraph library have methods to create them automatically assigned to the vsg::ObjectFactory, and the native VSG loaders internally use the ObjectFactory to create all the required objects, so for native .vsgt and .vsgb files one doesn't need to concern oneself with the ObjectFactory - it's simply something used internally by the VSG when loading files. +The core scene graph classes found in the VulkanSceneGraph library have creation methods automatically assigned to the vsg::ObjectFactory, and the native VSG loaders internally use the ObjectFactory to create all the required objects, so for native .vsgt and .vsgb files one doesn't need to concern oneself with the ObjectFactory - it's simply something used internally by the VSG when loading files. -For cases where applications extend the scene graph objects like with the above native::Animal example, users have to register their class with the ObjectFactory so that loaders can create an instance of it for each object of that type that the loader needs to create and read into. The ObjectFactory.h header provides the [vsg::RegisterWithObjectFactoryProxy](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/ObjectFactory.h#L54) template helper class to make this task straightforward. The following example includes a static declaration of the proxy object sp during initialization of the application, the required creation method will be automatically registered with the vsg::ObjectFactory singleton. +For cases where applications extend the scene graph objects (like with the native::Animal example below), users have to register their class with the ObjectFactory so that loaders can create an instance of it for each object of that type that the loader needs to create and read into. The ObjectFactory.h header provides the [vsg::RegisterWithObjectFactoryProxy](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/ObjectFactory.h#L54) template helper class to make this task straightforward. The following example includes a static declaration of the proxy object so that during initialization of the application, the required creation method will be automatically registered with the vsg::ObjectFactory singleton. ## Example of implementing serialization -While the range of methods in Input and Output is extensive and potentially overwhelming, usage of these classes is usually quite straightforward, with the template<> methods automatically handling support for you. The [serialization](https://github.com/vsg-dev/vsgTutorial/tree/master/2_Foundations/2_serialization) example illustrates how to implement custom serialization. +While the range of methods in Input and Output is extensive and potentially overwhelming, usage of these classes is usually quite straightforward, with the template<> methods automatically handling support for you. The [serialization](https://github.com/vsg-dev/vsgTutorial/tree/master/2_Foundations/2_serialization) example illustrates how to implement custom serialization. ~~~ cpp {% include_relative 2_serialization/serialization.cpp %} @@ -112,7 +112,7 @@ Root id=1 nature::Animal ## vsg::Input and vsg::Output subclasses -Orthogonal to the task of implementing serializers for user defined classes the underlying vsg::Input and vsg::Output that implement the integration with the underlying file/stream/memory are also extensible. The native .vsgt Ascii and .vsgb Binary file formats that the [vsg::VSG ReaderWriter](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/VSG.h#L24) provides are implemented via subclassing from vsg::Input and vsg::Output, these subclasses provide a good illustration of what is required, the following table provides links to the relevant header and source files for each of these subclasses: +Orthogonal to the task of implementing serializers for user defined classes the underlying vsg::Input and vsg::Output that implement the integration with the underlying file/stream/memory are also extensible. The native .vsgt Ascii and .vsgb Binary file formats that the [vsg::VSG ReaderWriter](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/VSG.h#L24) provides are implemented via subclassing from vsg::Input and vsg::Output, these subclasses provide a good illustration of what is required, the following table provides links to the relevant header and source files for each of these subclasses: | base class | subclass | header | source | | [vsg::Input](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Input.h#L40) | vsg::AsciiInput | [include/vsg/io/AsciiInput.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/AsciiInput.h#L26) | [src/vsg/io/AsciiInput.cpp](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/src/vsg/io/AsciiInput.cpp#L13) | @@ -120,7 +120,7 @@ Orthogonal to the task of implementing serializers for user defined classes the | [vsg::Input](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Input.h#L40) | vsg::BinaryInput | [include/vsg/io/BinaryInput.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/BinaryInput.h#L26) | [src/vsg/io/BinaryInput.cpp](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/src/vsg/io/BinaryInput.cpp#L13) | | [vsg::Output](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Output.h#L37) | vsg::BinaryOutput | [include/vsg/io/BinaryOutput.h](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/BinaryOutput.h#L24) | [src/vsg/io/BinaryOutput.cpp](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/src/vsg/io/BinaryOutput.cpp#L13) | -The [vsg::VSG ReaderWriter selects](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/src/vsg/io/VSG.cpp#L94) the appropriate Input/Output implementation based on the file extension, so for most usage cases there is never any need to create and invoke the Input/Output classes directly in your application. For most usage case there will also be no need to write your own subclasses from vsg::Input and vsg::Output, a possible exception would be subclassing from vsg::Input/vsg::Output to implement the reflection support required when integrating with 3rd party languages such as Lua/Python. This type of usage is an advanced topic beyond the scope of this online book, the existing implementations linked to above will be good starting place for seeing what would be required. +The [vsg::VSG ReaderWriter selects](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/src/vsg/io/VSG.cpp#L94) the appropriate Input/Output implementation based on the file extension, so for most use cases there is never any need to create and invoke the Input/Output classes directly in your application. For most use cases there will also be no need to write your own subclasses from vsg::Input and vsg::Output, a possible exception would be subclassing from vsg::Input/vsg::Output to implement the reflection support required when integrating with 3rd party languages such as Lua or Python. This type of usage is an advanced topic beyond the scope of this online book, the existing implementations linked to above will be a good starting place for seeing what would be required. Prev: [vsgXchange](vsgXchange.md) | Next : [File Systems](FileSystem.md) diff --git a/2_Foundations/StreamsAndLogger.md b/2_Foundations/StreamsAndLogger.md index e017372..7ef461e 100644 --- a/2_Foundations/StreamsAndLogger.md +++ b/2_Foundations/StreamsAndLogger.md @@ -4,11 +4,11 @@ title: Streams & Logger permalink: /foundations/StreamsAndLogger --- -A significant part of developing software is the process of reporting and logging results for the purpose of QA and debugging. C++ provides the std::ostream/std::istream operators for convinient textural formatting output and inputing of standard types, and the VulkanSceneGraph extends this to include native types. The library then adds additional support for recording textural with an extensible thread safe logger class. +A significant part of developing software is the process of reporting and logging results for the purpose of QA and debugging. C++ provides the std::ostream/std::istream operators for convenient textual formatting of output and input of standard types, and the VulkanSceneGraph extends this to include native types. The library then adds additional support for textual recording with an extensible thread safe logger class. ## istream & ostream operators -The [include/vsg/io/stream.h header](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/stream.h#L31) provides a collection of << and >> operators for a range of types making it convinient to use them with input/output streams: +The [include/vsg/io/stream.h header](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/stream.h#L31) provides a collection of << and >> operators for a range of types making it convenient to use them with input/output streams: ~~~ cpp vsg::vec3 position = {1.0, 2.0, 3.0}; @@ -60,7 +60,7 @@ str = You can compose a string from numbers i.e PI = 3.14, and vsg types like vs The [Logger.h header](https://github.com/vsg-dev/VulkanSceneGraph/tree/master/include/vsg/io/Logger.h#L25) provides the vsg::Logger base class and a series of subclasses that specialize it for different usage cases. -The [vsglog](https://github.com/vsg-dev/vsgExamples/blob/master/examples/io/vsglog/vsglog.cpp) example illustrates use the the standard vsg::Logger capabilities and how to write a custom Logger class. Console output from vsglog: +The [vsglog](https://github.com/vsg-dev/vsgExamples/blob/master/examples/io/vsglog/vsglog.cpp) example illustrates the use of the standard vsg::Logger capabilities and how to write a custom Logger class. Console output from vsglog: ~~~ sh $ vsglog @@ -89,7 +89,7 @@ custom warn : log warn custom error : log error ~~~ -The [vsglog_mt](https://github.com/vsg-dev/vsgExamples/blob/master/examples/io/vsglog/vsglog.cpp) example illustrates multireaded vsg::Logger. Console output from vsglog_mt: +The [vsglog_mt](https://github.com/vsg-dev/vsgExamples/blob/master/examples/io/vsglog/vsglog.cpp) example illustrates a multithreaded vsg::Logger. Console output from vsglog_mt: ~~~ sh $ vsglog_mt -n 10 -t 3 diff --git a/2_Foundations/Visitors.md b/2_Foundations/Visitors.md index efde822..e1ba6c9 100644 --- a/2_Foundations/Visitors.md +++ b/2_Foundations/Visitors.md @@ -4,9 +4,9 @@ title: Visitors permalink: /foundations/Visitors --- -The vsg::Visitor and vsg::ConstVisitor base classes are a variation of the [Visitor Design Pattern](https://en.wikipedia.org/wiki/Visitor_pattern) designed specifically for scene graphs. The particular challenge for scene graphs is that not only can there be many different types of objects in a scene graph, but how the children should be visited can also vary from node to node and from visitor to visitor. +The vsg::Visitor and vsg::ConstVisitor base classes are a variation of the [Visitor Design Pattern](https://en.wikipedia.org/wiki/Visitor_pattern) designed specifically for scene graphs. The particular challenge for scene graphs is that not only can there be many different types of objects in a scene graph, but how the children should be visited can also vary from node to node and from visitor to visitor. -To resolve this the Design Pattern's Object::accept(..)/Visitor::apply() method pairing is accompanied by a Object::traverse(..) method which is coupled with the Visitor taking resonisibility of traversal calling the Object::traverse() method when/where it is appropriate. In this section we will see how this is implemented, how you write and use your own visitors and advantages that this Visitor Design Pattern variation provides. +To resolve this the Design Pattern's Object::accept(..)/Visitor::apply() method pairing is accompanied by an Object::traverse(..) method which is coupled with the Visitor taking responsibility of traversal calling the Object::traverse(..) method when/where it is appropriate. In this section we will see how this is implemented, how you write and use your own visitors and the advantages that this Visitor Design Pattern variation provides. ## vsg::Object, vsg::Visitor and vsg::ConstVisitor API @@ -20,7 +20,7 @@ virtual void accept(ConstVisitor& visitor) const; virtual void traverse(ConstVisitor&) const {} ~~~ -The [vsg::Inherit<>](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Inherit.h) template class provides implementations for the accept(Visitor&) and accept(ConstVisitor&) virtual functions, note the visitor.apply(..) which follows the Visitor Design Pattern convention of a Object::accept(..)/Visitor::apply(..) pairing: +The [vsg::Inherit<>](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Inherit.h) template class provides implementations for the accept(Visitor&) and accept(ConstVisitor&) virtual functions, note the visitor.apply(..) which follows the Visitor Design Pattern convention of an Object::accept(..)/Visitor::apply(..) pairing: ~~~ cpp void accept(Visitor& visitor) override { visitor.apply(static_cast(*this)); } @@ -28,7 +28,7 @@ void accept(ConstVisitor& visitor) const override { visitor.apply(static_cast(value)); } void Visitor::apply(stringValue& value) { - // if Visitor::apply(stringValue& value) isn't implemented by Visitor subclass this + // if Visitor::apply(stringValue& value) isn't implemented by the Visitor subclass, this // default implementation will be invoked and cast to parent class Data and call above method apply(static_cast(value)); } @@ -97,9 +97,9 @@ This cascading simplifies implementations so they only need to override specific ## Traversal under your control -By design none of the default apply(..) methods provided by vsg::Visitor and vsg::ConstVisitor provide traversal support, the decision on which objects to traverse and how to traverse them is left to visitor subclasses. The vsg::Object::traverse(..) method can be used by Visitor subclasses to handle traversal of an objects children when this is required, or Visitor subclasses can implement their own traversal of an objects children. +By design none of the default apply(..) methods provided by vsg::Visitor and vsg::ConstVisitor undertake any type of traversal, the decision on which objects to traverse and how to traverse them is left to visitor subclasses. The vsg::Object::traverse(..) method can be used by Visitor subclasses to handle traversal of an object's children when this is required, or Visitor subclasses can implement their own traversal of an object's children. -One of the advantages of giving responsibility to the visitor implementation is you can do operations before and after traversing a subgraph, for instance we use this to increment/decrment an indent as we traverse a graph. The following is a snippet from the PrintVisitor example that we'll expand upon later in this section. +One of the advantages of giving responsibility to the visitor implementation is you can do operations before and after traversing a subgraph, for instance we use this to increment/decrement an indent as we traverse a graph. The following is a snippet from the PrintVisitor example that we'll expand upon later in this section. ~~~ cpp struct PrintVisitor : public vsg::Inherit @@ -125,11 +125,11 @@ Mask traversalMask = MASK_ALL; Mask overrideMask = MASK_OFF; ~~~ -Subgraph will be visited when the result of `(nodeMask | visitor.overrideMask) & visitor.traversalMask)!=0`. In the chapters 3 & 4 chapters we'll go into the use of node and traversal masks in detail when scene graph nodes and application level classes that use them. +A subgraph will be visited when the result of `(nodeMask | visitor.overrideMask) & visitor.traversalMask)!=0`. In chapters 3 & 4 we'll go into the use of node and traversal masks in detail, showing scene graph nodes and application level classes that use them. ## PrintVisitor example -The following [PrintVisitor](https://github.com/vsg-dev/vsgTutorial/blob/master/2_Foundations/2_PrintVisitor/) example does traversal of a graph and provide methods to print out specific properties associated with types of interest: +The following [PrintVisitor](https://github.com/vsg-dev/vsgTutorial/blob/master/2_Foundations/2_PrintVisitor/) example does traversal of a graph and provides methods to print out specific properties associated with types of interest: ~~~ cpp struct PrintVisitor : public vsg::Inherit @@ -180,7 +180,7 @@ auto root = vsg::Objects::create(); root->addChild(vsg::stringValue::create("Everybody Loves Raymond")); root->addChild(nested); -// consutruct our visitor and then pass it to root node to invoke the visitor. +// construct our visitor and then pass it to root node to invoke the visitor. PrintVisitor print; root->accept(print); ~~~ @@ -198,12 +198,12 @@ Visiting vsg::Objects ## Visitors provided by the VulkanSceneGraph project -The VulkanSceneGraph uses visitors for utilities for end users as well as using them to implement core features. In addition to providing useful functionality they also serve as a good example of the range of tasks you can tackle with visitors, and how to implement your own. When reviewing the following examples look for the apply(..) methods that override the base Visitor/ConstVisitor::apply(..) methods as guide to what type of objects that handle: +The VulkanSceneGraph employs visitors for utilities for end users as well as using them to implement core features. In addition to providing useful functionality, the built in visitors also serve as a good example of the range of tasks you can tackle with them, and how to implement your own. When reviewing the following examples look for the apply(..) methods that override the base Visitor/ConstVisitor::apply(..) methods as a guide to what type of objects they handle: ### Event handling: | Class | Header | Description | -| CountGlyphs | [text/Text.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/text/Text.h#L63) | Utility for count text glyphs | +| CountGlyphs | [text/Text.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/text/Text.h#L63) | Utility for counting text glyphs | | CollectEvents | [ui/CollectEvents.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/ui/CollectEvents.h#L22) | Collects events | | PlayEvents | [ui/PlayEvents.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/ui/PlayEvents.h#L22) | Plays events | | RecordEvents | [ui/RecordEvents.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/ui/RecordEvents.h#L23) | Records events for later playback | @@ -220,35 +220,35 @@ The VulkanSceneGraph uses visitors for utilities for end users as well as using | FindCameras | [app/Camera.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/Camera.h#L46) | Find all the Cameras in a graph | | ShaderCompiler | [utils/ShaderCompiler.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/ShaderCompiler.h#L10) | Compile GLSL shaders to SPIR-V | | ComputeBounds | [utils/ComputeBounds.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/ComputeBounds.h#L21) | Compute the bounds of a subgraph | -| LoadPagedLOD | [utils/LoadPagedLOD.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/LoadPagedLOD.h#L23) | Preload PageLOD children | +| LoadPagedLOD | [utils/LoadPagedLOD.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/LoadPagedLOD.h#L23) | Preload PagedLOD children | | Intersector | [utils/Intersector.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/Intersector.h#L21) | Intersector base class | | ArrayState | [state/ArrayState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ArrayState.h#L24) | Track the array bindings in the scene graph during traversal | ### Application setup: | Class | Header | Description | -| CollectResourceRequirements | [vk/ResourceRequirements.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master//include/vsg/vk/ResourceRequirements.h#L92) | Collects all the resources required by a scene graph| -| CompileTraversal | [app/CompileTraversal.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/CompileTraversal.h#L31) | Create Vulkan objects and transfer data to the GPU | -| WindowResizeHandler | [app/WindowResizeHandler.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/WindowResizeHandler.h#L24) | Updates the GraphicsPipeline in a scene graph for new viewport dimensions | +| CollectResourceRequirements | [vk/ResourceRequirements.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master//include/vsg/vk/ResourceRequirements.h#L92) | Collects all the resources required by a scene graph | +| CompileTraversal | [app/CompileTraversal.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/CompileTraversal.h#L31) | Creates Vulkan objects and transfers data to the GPU | +| WindowResizeHandler | [app/WindowResizeHandler.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/WindowResizeHandler.h#L24) | Updates the GraphicsPipelines in a scene graph for new viewport dimensions | ## RecordTraversal -The RecordTraversal class is similar to the visitor classes but it's implemented with the double dispatch (two virtual functions) that the visitor classes use. The RecordTraversal is is supported by [vsg::Object](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Object.h#L85) via the two virtual methods: +The RecordTraversal class is similar to the visitor classes but it's not implemented with the double dispatch (two virtual functions) that the visitor classes use. The RecordTraversal is supported by [vsg::Object](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Object.h#L85) via the two virtual methods: ~~~ cpp virtual void accept(RecordTraversal& visitor) const; virtual void traverse(RecordTraversal&) const {} ~~~ -The part that is different is the [RecordTraversal::apply()](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/RecordTraversal.h#L97) methods are straightforward class methods rather than virtual methods like those used in visitors. This is done to reduce the number of virtual functions being invoked during the traversal that is most critical to performance, but does mean that one can't subclass from RecordTraversal and override the apply methods - the choice is to favor performance over extensibility. +The part that is different are the [RecordTraversal::apply()](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/RecordTraversal.h#L97) methods which are straightforward class methods rather than virtual methods like those used in visitors. This is done to reduce the number of virtual functions being invoked during the traversal that is most critical to performance, but does mean that one can't subclass from RecordTraversal and override the apply methods - the choice is to favor performance over extensibility. While the RecordTraversal itself is not designed to be extended, users can implement custom nodes that override the vsg::Object's virtual apply(RecordTraversal) & traverse(RecordTraversal&) methods to customize how the RecordTraversal handles the custom nodes. ## Visitor and user defined subclasses -One of weakensses of the Visitor Design Pattern is that the Visitor class must have a virtual apply(..) method for each supported type, if a user presents a new subclass that isn't directly supported it will be treated as the subclasses parent class. For instance if you create a vsg::MyData subclass from vsg::Data when passed to a vsg::Visitor it will be matched to the Visitor::apply(Data&) method. +One of the weaknesses of the Visitor Design Pattern is that the Visitor class must have a virtual apply(..) method for each supported type, if a user presents a new subclass that isn't directly supported it will be treated as the subclasses parent class. For instance if you create a vsg::MyData subclass from vsg::Data, when passed to a vsg::Visitor it will be matched to the Visitor::apply(Data&) method. -The vsgExmaples repository contains the [vsgvisitorcustomtype](https://github.com/vsg-dev/vsgExamples/tree/master/examples/core/vsgvisitorcustomtype) example that illustrates two approaches to extending visitor types. +The vsgExamples repository contains the [vsgvisitorcustomtype](https://github.com/vsg-dev/vsgExamples/tree/master/examples/core/vsgvisitorcustomtype) example that illustrates two approaches to extending visitor types. --- diff --git a/2_Foundations/index.md b/2_Foundations/index.md index 708fb67..ac69aa2 100644 --- a/2_Foundations/index.md +++ b/2_Foundations/index.md @@ -4,16 +4,16 @@ title: Foundations permalink: /foundations/ --- -**Currently being written.** +**The first draft of this chapter is now complete. We'll make corrections and refine it over the coming weeks** -This second part of this tutorial introduces developers to foundational classes and features that the rest of the VulkanSceneGraph classes are built upon. We start with introducing the base class and smart pointers, the vector and matrix types, the data containers and meta data. +The second part of this tutorial introduces developers to foundational classes and features that the rest of the VulkanSceneGraph classes are built upon. We start with introducing the base classes and smart pointers, the vector and matrix types, the data containers and meta data. 1. [vsg::ref_ptr<> & vsg::Object base class](Object_base_class_and_ref_ptr.md) - strong smart pointer with intrusive reference counting 1. [vsg::observer_ptr<>](observer_ptr.md) - weak smart pointers 1. [Math Types](MathTypes.md) - GLSL style data types 1. [Data Types](DataTypes.md) - vsg::Value, Array, Array2D & Array3D 1. [Metadata](Metadata.md) - how to use metadata -1. [RTTI](RTTI.md) - Run Time Time Identification (RTTI) features +1. [RTTI](RTTI.md) - Run Time Type Information (RTTI) features 1. [Visitors](Visitors.md) - type safe visiting and traversal 1. [read/write](ReaderWriter.md) - reading/writing data 1. [vsgXchange](vsgXchange.md) - vsgXchange library for reading 3rd party image/model formats @@ -21,4 +21,4 @@ This second part of this tutorial introduces developers to foundational classes 1. [File System](FileSystem.md) - File system classes and functions 1. [Streams and Logger](StreamsAndLogger.md) - General stream and Logger support 1. [vsg::Allocator](Allocator.md) - Block memory allocation for good performance -1. [Math Functions](MathFunctionss.md) - math functions +1. [Math Functions](MathFunctions.md) - math functions diff --git a/2_Foundations/observer_ptr.md b/2_Foundations/observer_ptr.md index 5105796..d9cce85 100644 --- a/2_Foundations/observer_ptr.md +++ b/2_Foundations/observer_ptr.md @@ -4,7 +4,7 @@ title: vsg::observer_ptr<> weak pointer permalink: /foundations/observer_ptr --- -All is not perfect in the realm of reference counted smart pointers like std::shared_ptr<> and vsg::ref_ptr<>, their biggest weakness is cases where data structures have circular references. A classic example of circular references is a parent owning a child, while the child has a smart pointer back to parent also owning the parent. When this happens the reference count for both the parent and child will remain non zero even if all other external references to them are removed - leading to a chain of objects that never gets deleted. +All is not perfect in the realm of reference counted smart pointers like std::shared_ptr<> and vsg::ref_ptr<>, their biggest weakness is in cases where data structures have circular references. A classic example of circular references is a parent owning a child, while the child has a smart pointer back to parent also owning the parent. When this happens the reference count for both the parent and child will remain non zero even if all other external references to them are removed - leading to a chain of objects that never get deleted. ~~~ cpp struct Animal : public vsg::Inherit @@ -17,14 +17,14 @@ struct Animal : public vsg::Inherit auto parent = Animal::create(); // parent object has ref count of 1 auto child = Animal::create(); // child object has ref count of 1 child->parent = parent; // parent object now has ref count of 2 - parent->children.push_back(child) // child object now has a ref count 2 -} // parent and child pointers destructed decrementing ref counts of both to 1 + parent->children.push_back(child) // child object now has a ref count of 2 +} // parent and child pointers destructed, decrementing ref counts of both to 1 // both the original parent object and child object still have a ref count of 1 // but there are no external references left to them so code has no knowledge of them or means to delete them ~~~ -This problem exists for std::shared_ptr<> for exactly the same reasons. One way to break the chain is to use a C pointer: +This problem exists for std::shared_ptr<> for exactly the same reasons. One way to break the chain is to use a C pointer: ~~~ cpp struct Animal : public vsg::Inherit @@ -37,22 +37,22 @@ struct Animal : public vsg::Inherit auto parent = Animal::create(); // parent object has ref count of 1 auto child = Animal::create(); // child object has ref count of 1 child->parent = parent.get(); // parent object ref count doesn't change as we are just assigning a C pointer - parent->children.push_back(child) // child object now ha a ref count 2 + parent->children.push_back(child) // child object now has a ref count of 2 } -// parent is descrtructed decreatment the parent object to 0 and the objects destructor is called. -// the destructor deletes the children list and destrements the child's reference count to 1. -// the child is destructed and decrements it's reference count to 0, deleting the child. +// parent is destructed, decrements the parent object to 0 and the object's destructor is called. +// the destructor deletes the children list and decrements the child's reference count to 1. +// the child is destructed and decrements its reference count to 0, deleting the child. ~~~ -While the use of C pointer breaks the chain in this instance, it has it's own pitfalls - if a parent gets deleted but a child remains due to other references to it the Animal::parent member will become a dangling pointer.To fix this one has to reset the Animal::parent pointer when the child is removed but do this robustly requires careful management of adding/removing of child to/from the Animal::children list. +While the use of C pointer breaks the chain in this instance, it has its own pitfalls - if a parent gets deleted but a child remains due to other references to it, the Animal::parent member will become a dangling pointer. To fix this one has to reset the Animal::parent pointer when the child is removed but doing this robustly requires careful management of adding/removing of children to/from the Animal::children list. -A common way to do this would be by adding a Animal::addChild(Animial*) and Animal::removeChild(Animal*) method. To protect from misuse one would also move the Animal::children container into protected scope to avoid misuse. However, this all adds complexity and requires tight integration of the various classes that you wish to connect. +A common way to do this would be by adding an Animal::addChild(Animal*) and Animal::removeChild(Animal*) method. To protect from misuse one would also move the Animal::children container into protected scope to avoid misuse. However, this all adds complexity and requires tight integration of the various classes that you wish to connect. ## Weak pointers to the rescue -To address the problem of circular references and make easier it keep pointers to objects without retaining ownership, there is catogory of smart pointers - weak pointers. Weak pointers hold a pointer to an object without incrementing the objects reference count, and when the object gets deleteted all the weak pointers that reference it have their pointer invalidated automatically, these weak pointers are paired with strong pointers. The std::shared_ptr<> strong pointer is paired with the std::weak_ptr<> weak pointer. For the VulkanSceneGraph the vsg::ref_ptr<> strong pointer is paired with the vsg::observer_ptr<>. +To address the problem of circular references and make it easier to keep pointers to objects without retaining ownership, there is another category of smart pointers - weak pointers. Weak pointers hold a pointer to an object without incrementing the object's reference count, and when the object gets deleted all the weak pointers that reference it have their pointer invalidated automatically, these weak pointers are paired with strong pointers. The std::shared_ptr<> strong pointer is paired with the std::weak_ptr<> weak pointer. For the VulkanSceneGraph the vsg::ref_ptr<> strong pointer is paired with the vsg::observer_ptr<>. -We can now rewirite the Animal example using the vsg::observer_ptr<>: +We can now rewrite the Animal example using the vsg::observer_ptr<>: ~~~ cpp struct Animal : public vsg::Inherit @@ -65,22 +65,22 @@ struct Animal : public vsg::Inherit auto parent = Animal::create(); // parent object has ref count of 1 auto child = Animal::create(); // child object has ref count of 1 child->parent = parent; // parent object ref count doesn't change as we are just assigning to a vsg::obsever_ptr<> - parent->children.push_back(child) // child object now ha a ref count 2 + parent->children.push_back(child) // child object now has a ref count of 2 } -// parent pointer is destructed and decreaments the parent object's ref count to 0 and the parent object destructor is called. +// parent pointer is destructed and decrements the parent object's ref count to 0 and the parent object destructor is called. // The destructor deletes the children list which decrements the child's reference count to 1. -// The child pointer is destructed and decrements it's reference count to 0, deleting the child. +// The child pointer is destructed and decrements its reference count to 0, deleting the child. ~~~ ## Using observer_ptr<> & ref_ptr<> together -The vsg::observer_ptr<> is also useful for cases where applications want to keep a pointer to a resource that has a lifetime that is independently managed, but you occasional want to access it if it's still in memory. The following observer_ptr example program uses a background thread that periodically checks a share resourced, only taking a reference to it when required to prevent it being deleted whilst being used, and exiting the thread when that resource was be deleted by the main thread. +The vsg::observer_ptr<> is also useful for cases where applications want to keep a pointer to a resource that has a lifetime that is independently managed, but you occasionally want to access it if it's still in memory. The following observer_ptr example program uses a background thread that periodically checks a shared resource, only taking a reference to it when required to prevent it from being deleted whilst being used, and exiting the thread when that resource was deleted by the main thread. ~~~ cpp {% include_relative 2_observer_ptr/observer_ptr.cpp %} ~~~ -When we compile and run the [observer_ptr](https://github.com/vsg-dev/vsgTutorial/tree/master/2_Foundations/2_observer_ptr) exercise we should see, note the changing reference count as the background thread converts it's obsever_ptr to ref_ptr. +When we compile and run the [observer_ptr](https://github.com/vsg-dev/vsgTutorial/tree/master/2_Foundations/2_observer_ptr) exercise, we should note the changing reference count as the background thread converts its observer_ptr to ref_ptr. ~~~ Main thread : scene = ref_ptr(vsg::Object 0x7f8d8c585010) referenceCount = 1 diff --git a/2_Foundations/vsgXchange.md b/2_Foundations/vsgXchange.md index 843ad6b..d47ec1d 100644 --- a/2_Foundations/vsgXchange.md +++ b/2_Foundations/vsgXchange.md @@ -4,14 +4,38 @@ title: vsgXchange - 3rd party formats support permalink: /foundations/vsgXchange --- -The [vsgXchange library](https://github.com/vsg-dev/vsgXchange) is a companion library that provides support for a range of 3rd party image and model file formats and http support. A number of these features require external dependencies that are checked for by CMake when building vsgXchange, if they are found the associated ReaderWriter is built and included in the vsgXchange::all composite ReaderWriter, you can assign this to the vsg::Options object as in the example above to add support for all the available formats, or you can add each ReaderWriter individually. Doing the later allows you to control the order in which ReaderWriters are invoked as well select just the ones that are important to your application and reduce the overall footprint of your application. +The [vsgXchange library](https://github.com/vsg-dev/vsgXchange) is a companion library that provides support for a range of 3rd party image and model file formats and http support. A number of these features require external dependencies that are checked for by CMake when building vsgXchange, if they are found the associated ReaderWriter is built and included in the vsgXchange::all composite ReaderWriter, you can assign this to the vsg::Options object as in the example below to add support for all the available formats, or you can add each ReaderWriter individually. Doing the latter allows you to control the order in which ReaderWriters are invoked as well as to select just the ones that are important to your application in order to reduce the overall footprint of your application. + +## Usage + +vsgXchange is leveraged by assigning the ReaderWriters it provides to a vsg::Options object, then passing this to the vsg::read/write calls. The vsgXchange::all composite ReaderWriter adds support for all the file formats provided by vsgXchange. Here's an example of usage: + +~~~ cpp +#include +#include + +{ + // create options object that is used to guide IO operations + auto options = vsg::Options::create(); + options->add(vsgXchange::all::create()); + + // read a GLTF model + auto model = vsg::read_cast("mymodel.gltf", options); + + // read a JPEG image + auto image = vsg::read_cast("myimage.jpg", options); + + // read a model from the internet leveraging the libcurl ReaderWriter + auto scene = vsg::read_cast("https://www.myserver.com/mypageddatabase.vsgb", options); +} +~~~ ## Supported formats -While the implementation of ReaderWriter that have external dependencies is only compiled when they are available, the public interface for all possible ReaderWriter is declared in the [include/vsgXchange](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/) directory. The way the fixed public interface is decoupled from optionally built implementation is using the [Fascade Design Pattern](https://en.wikipedia.org/wiki/Facade_pattern), with the public ReaderWriter classes deferring their implementations provided by either a fallback non op implementation or the full implementation when the dependency is available. The available ReaderWriter's, the asscoiated dependencies and the formats supported are: +While the implementation of ReaderWriters that have external dependencies are only compiled in when they are available, the public interface for all possible ReaderWriter is declared in the [include/vsgXchange](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/) directory. The way the fixed public interface is decoupled from the optionally built implementation is using the [Fascade Design Pattern](https://en.wikipedia.org/wiki/Facade_pattern), with the public ReaderWriter classes deferring their implementations, they are provided by either a fallback non op implementation or the full implementation when the dependency is available. The available ReaderWriters, the associated dependencies and the formats supported are: | ReaderWriter | Dependency | Features | -| [vsgXchange::all](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/all.h#L35) | | Composite ReaderWriter that bundles all supported ReaderWriter's support by core VSG and vsgXchange | +| [vsgXchange::all](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/all.h#L35) | | Composite ReaderWriter that bundles all ReaderWriters supported by core VSG and vsgXchange | | [vsgXchange::images](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/images.h#L34) | | Bundles all supported image ReaderWriters | | [vsgXchange::models](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/models.h#L34) | | Bundles all supported model ReaderWriters | | [vsgXchange::stbi](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/images.h#L42) | | Support for PNG, JPEG, GIF images | @@ -25,7 +49,7 @@ While the implementation of ReaderWriter that have external dependencies is only | [vsgXchange::osg2vsg](https://github.com/vsg-dev/vsgXchange/blob/master/include/vsgXchange/models.h#L41) | [osg2vsg](https://github.com/vsg-dev/osg2vsg) | Read OpenSceneGraph supported image and model formats | -vsgXchange's CMake scripts automatically generated include/vsgXchange/Version.h header provides #define's for each ReaderWriter so you can test at compile time if you so wish, and each optionally compiled ReaderWriter has a flag to say whether it's supported or not, so you can test for it at runtime. What follows is what you'll see in the Version.h header's if you have built against all the dependencies: +vsgXchange's CMake scripts automatically generate the include/vsgXchange/Version.h header that provides #define's for each ReaderWriter so you can test at compile time if you so wish, and each optionally compiled ReaderWriter has a flag to say whether it's supported or not, so you can test for it at runtime. What follows is what you'll see in the Version.h header if you have built against all the dependencies: ~~~ cpp /// standard Features @@ -47,7 +71,7 @@ vsgXchange's CMake scripts automatically generated include/vsgXchange/Version.h #define vsgXchange_OSG ~~~ -At runtime to list the supported features you call the ReaderWriter::getFeatures(Features&) method, this returns true when the ReaderWriter is implemented and adds the supported features to the feature structure, and returns false if the format is not supported - such as when vsgXchange is not compiled against the required dependency. +To list the supported features at runtime, you call the ReaderWriter::getFeatures(Features&) method, this returns true when the ReaderWriter is implemented and adds the supported features to the feature structure, and returns false if the ReaderWriter is not supported - such as when vsgXchange is not compiled against the required dependency. ## vsgconv @@ -365,6 +389,12 @@ vsgXchange::all write_build_options string ~~~ +Options specific to a ReaderWriter are specified on the commandline using two dashes: + +~~~ sh +vsgconv FlightHelmet.gltf helmet.vsgb --discard_empty_nodes false +~~~ + # Using vsgXchange::cpp & vsgconv to create compilable objects The vsgXchange::cpp ReaderWriter enables programmers to convert all vsg::Object types to source files that can be included into the build of your applications, this can be used for data, scene graphs or shaders/shadersets. You can use vsgconv to do this conversion in the console: @@ -373,7 +403,7 @@ The vsgXchange::cpp ReaderWriter enables programmers to convert all vsg::Object vsgconv shaders/shader.vert shader_vert.cpp ~~~ -The generated shader_vert.cpp looks like: +The generated shader_vert.cpp looks like this: ~~~ cpp #include @@ -461,7 +491,7 @@ return io.read_cast(reinterpret_cast(str), siz }; ~~~ -In the above example the vsgconv utility has automatically compiles the GLSL shader source to SPIRV code for you, so at runtime there is no need for the VSG to compile the shader. You can then invoke this from your C++ code: +In the above example the vsgconv utility has automatically compiled the GLSL shader source to SPIRV code for you, so at runtime there is no need for the VSG to compile the shader. You can then invoke this from your C++ code: ~~~ cpp @@ -474,7 +504,7 @@ In the above example the vsgconv utility has automatically compiles the GLSL sha } ~~~ -Examples of compiling objects as part of library/application can be found in the VulkanSceneGraph codebase, for instance the text related shaders are used in [VulkanScenegraph/src/vsg/text/Text.cpp](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/src/vsg/text/Text.cpp#L69) which includes the [VulkanScenegraph/src/vsg/text/shaders/text_ShaderSet.cpp](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/src/vsg/text/shaders/text_ShaderSet.cpp). The text_ShaderSet.cpp is created by the [vsgshaderset](https://github.com/vsg-dev/vsgExamples/tree/master/examples/utils/vsgshaderset) utility found in vsgExamples. +Examples of compiling objects into libraries/applications can be found in the VulkanSceneGraph codebase, for instance the text related shaders are used in [VulkanSceneGraph/src/vsg/text/Text.cpp](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/src/vsg/text/Text.cpp#L69) which includes the [VulkanSceneGraph/src/vsg/text/shaders/text_ShaderSet.cpp](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/src/vsg/text/shaders/text_ShaderSet.cpp). The text_ShaderSet.cpp is created by the [vsgshaderset](https://github.com/vsg-dev/vsgExamples/tree/master/examples/utils/vsgshaderset) utility found in vsgExamples. Prev: [read/write](ReaderWriter.md) | Next : [Serialization](../2_Foundations/Serialization.md) diff --git a/3_SceneGraph/Commands.md b/3_SceneGraph/Commands.md new file mode 100644 index 0000000..2f23cef --- /dev/null +++ b/3_SceneGraph/Commands.md @@ -0,0 +1,91 @@ +--- +layout: page +title: Commands +permalink: /scenegraph/Commands +--- + +The class definitions for the Vulkan command nodes of the scene graph can be found in the [VulkanSceneGraph/include/vsg/commands](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/) directory. Examples that illustrate use of various command classes can be found in the [vsgExamples/examples/commands](https://github.com/vsg-dev/vsgExamples/tree/master/examples/commands) directory. + +## Command base and group classes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Compilable | [Compilable.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Compilable.h) | Base class for objects that can be compiled | +| vsg::Command | [Command.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Command.h) | Base class for vkCmd* types| +| vsg::Commands | [Commands.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Commands.h) | Group of vsg::Command | + +## Binding index and vertex array buffers + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::BindIndexBuffer | [BindIndexBuffer.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BindIndexBuffer.h) | [vkCmdBindIndexBuffer](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBindIndexBuffer.html) | +| vsg::BindVertexBuffers | [BindVertexBuffers.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BindVertexBuffers.h) | [vkCmdBindVertexBuffers](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBindVertexBuffers.html) | + +## Draw primitive commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Draw | [Draw.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Draw.h) | [vkDraw](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdDraw.html) | +| vsg::DrawIndexed | [DrawIndexed.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/DrawIndexed.h) | [vkDrawIndexed](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdDrawIndexed.html) | +| vsg::DrawIndexedIndirect | [DrawIndexedIndirect.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/DrawIndexedIndirect.h) | [vkCmdDrawIndexedIndirect](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdDrawIndexedIndirect.html) | +| vsg::DrawIndirectCommand | [DrawIndirectCommand.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/DrawIndirectCommand.h) | [vkCmdDrawIndirectCommand](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDrawIndexedIndirectCommand.html) | +| vsg::DrawIndirect | [DrawIndirect.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/DrawIndirect.h) | [vkCmdDrawIndirect](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdDrawIndirect.html) | + +## Copy commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::CopyImage | [CopyImage.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/CopyImage.h) | | +| vsg::CopyImageToBuffer | [CopyImageToBuffer.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/CopyImageToBuffer.h) | | +| vsg::CopyImageViewToWindow | [CopyImageViewToWindow.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/CopyImageViewToWindow.h) | | +| vsg::CopyAndReleaseBuffer | [CopyAndReleaseBuffer.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/CopyAndReleaseBuffer.h) | | + +## Image commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::BlitImage | [BlitImage.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BlitImage.h) | | +| vsg::ResolveImage | [ResolveImage.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/ResolveImage.h) | | + +## Compute commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Dispatch | [Dispatch.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Dispatch.h) | | + +# Syncronization commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Event | [Event.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Event.h) | | +| vsg::PipelineBarrier | [PipelineBarrier.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/PipelineBarrier.h) | | + +## Higher level commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::ClearAttachments | [ClearAttachments.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/ClearAttachments.h) | | +| vsg::ExecuteCommands | [ExecuteCommands.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/ExecuteCommands.h) | | +| vsg::NextSubPass | [NextSubPass.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/NextSubPass.h) | | + +## Dynamic state commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::SetDepthBias | [SetDepthBias.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/SetDepthBias.h) | | +| vsg::SetLineWidth | [SetLineWidth.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/SetLineWidth.h) | | +| vsg::SetScissor | [SetScissor.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/SetScissor.h) | | +| vsg::SetViewport | [SetViewport.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/SetViewport.h) | | + +## Query commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::BeginQuery | [BeginQuery.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BeginQuery.h) | | +| vsg::EndQuery | [EndQuery.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/EndQuery.h) | | +| vsg::ResetQueryPool | [ResetQueryPool.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/ResetQueryPool.h) | | +| vsg::CopyQueryPoolResults | [CopyQueryPoolResults.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/CopyQueryPoolResults.h) | | +| vsg::WriteTimestamp | [WriteTimestamp.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/WriteTimestamp.h) | | + +Prev: [Nodes](Nodes.md)| Next: [State](State.md) + diff --git a/3_SceneGraph/MeshShaders.md b/3_SceneGraph/MeshShaders.md new file mode 100644 index 0000000..745e28c --- /dev/null +++ b/3_SceneGraph/MeshShaders.md @@ -0,0 +1,15 @@ +--- +layout: page +title: Mesh Shaders +permalink: /scenegraph/MeshShaders +--- + +The class definitions for the Vulkan mesh shader nodes of the scene graph can be found in the [VulkanSceneGraph/include/vsg/meshshaders](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/meshshaders/) directory. + +| Class | Header | Functionality | +| | [DrawMeshTasks.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/meshshaders/) | | +| | [DrawMeshTasksIndirectCount.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/meshshaders/) | | +| | [DrawMeshTasksIndirect.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/) | | + +Prev: [State](State.md)| Next : [Ray Tracing](RayTracing.md) + diff --git a/3_SceneGraph/Nodes.md b/3_SceneGraph/Nodes.md new file mode 100644 index 0000000..68d5721 --- /dev/null +++ b/3_SceneGraph/Nodes.md @@ -0,0 +1,65 @@ +--- +layout: page +title: Nodes +permalink: /scenegraph/Nodes +--- + +The class definitions for the internal nodes of the scene graph can be found in the [VulkanSceneGraph/include/vsg/nodes](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/) directory. All scene graph nodes are subclassed from the vsg::Node base class. Examples that illustrate use of various node classes can be found in the [vsgExamples/examples/nodes](https://github.com/vsg-dev/vsgExamples/tree/master/examples/nodes) directory. + +## Node Base class + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Node | [Node.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Node.h) | Node base class | + +## Group nodes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Group | [Group.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Group.h) | Group node | +| vsg::QuadGroup | [QuadGroup.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/QuadGroup.h) | QuadGroup is a fixed sized group for building high performance quad trees | +| vsg::Switch | [Switch.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Switch.h) | Switch node provides support for switching between children | + +## Culling nodes + +| Class| Header | Functionality | +| --- | --- | --- | +| vsg::CullGroup | [CullGroup.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/CullGroup.h) | Culling group that culls a bounding sphere against view frustum | +| vsg::CullNode | [CullNode.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/CullNode.h) | Culling node that culls a bounding sphere against view frustum | +| vsg::LOD | [LOD.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/LOD.h) | Level of Detail node that culls based on projected size of bounding sphere | +| vsg::PagedLOD | [PagedLOD.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/PagedLOD.h) | Level of Detall node that has a low res child and high res child with file reference | +| vsg::TileDatabase | [TileDatabase.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/TileDatabase.h) | | + +## Transformation nodes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Transform| [Transform.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Transform..h) | Transform base class for nodes that provide an interface for defining transforms of a subgraph | +| vsg::MatrixTransform | [MatrixTransform.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/MatrixTransform.h) | Transform node that provides a 4x4 matrix to transform relative to parent coordinate frame | +| vsg::AbsoluteTransform | [AbsoluteTransform.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/AbsoluteTransform.h) | Transform node that provides a 4x4 matrix that ignores parent coordinate frame to provide an absolute frame of reference | + +## Geometry nodes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Geometry | [Geometry.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Geometry.h) | General purpose geometry node, provides a list of arrays and list of draw commands | +| vsg::VertexDraw | [VertexDraw.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/VertexDraw.h) | High performance geometry node, provides a list of arrays and a single draw command | +| vsg::VertexIndexDraw | [VertexIndexDraw.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/VertexIndexDraw.h) | High performance geometry node, provides a list of arrays, an index array and a single indexed draw command | + +## State nodes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::StateGroup | [StateGroup.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/StateGroup.h) | State group node that provides a list of StateCommands to decorate a subgraph | +| vsg::Light | [Light.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Light.h) | Light node provides all the settings for positioning a light source, and controlling its type and color | + +## Draw order control + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::Bin | [Bin.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Bin.h) | Bin node provides a way of controlling the record order of its children | +| vsg::DepthSorted | [DepthSorted.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/DepthSorted.h) | Depth sorted node provides controls for depth sorting of its subgraph | + + +Prev: [Scene Graph](index.md)| Next: [Commands](Commands.md) + diff --git a/3_SceneGraph/RayTracing.md b/3_SceneGraph/RayTracing.md new file mode 100644 index 0000000..fb63931 --- /dev/null +++ b/3_SceneGraph/RayTracing.md @@ -0,0 +1,21 @@ +--- +layout: page +title: Ray Tracing +permalink: /scenegraph/RayTracing +--- + +The class definitions for the Vulkan ray tracing nodes of the scene graph can be found in the [VulkanSceneGraph/include/vsg/raytracing](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) directory. + +| Class | Header | Functionality | +| | [AccelerationGeometry.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [AccelerationStructure.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [BottomLevelAccelerationStructure.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [BuildAccelerationStructureTraversal.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [DescriptorAccelerationStructure.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [RayTracingPipeline.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [RayTracingShaderGroup.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [TopLevelAccelerationStructure.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | +| | [TraceRays.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/raytracing/) | | + +Prev: [Mesh Shaders](MeshShaders.md)| Next : [osg2vsg](osg2vsg.md) + diff --git a/3_SceneGraph/State.md b/3_SceneGraph/State.md new file mode 100644 index 0000000..b37e538 --- /dev/null +++ b/3_SceneGraph/State.md @@ -0,0 +1,79 @@ +--- +layout: page +title: State +permalink: /scenegraph/State +--- + +The class definitions for the Vulkan state nodes of the scene graph can be found in the [VulkanSceneGraph/include/vsg/state](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/) directory. Examples that illustrate use of various state classes can be found in the [vsgExamples/examples/state](https://github.com/vsg-dev/vsgExamples/tree/master/examples/state) directory, + +## Scene graph state nodes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::StateCommand | [StateCommand.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/) | Base class for state commands - binding pipelines & descriptors | +| vsg::StateGroup | [StateGroup.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/StateGroup.h) | State group node that provides a list of StateCommands to decorate a subgraph | +| vsg::Light | [Light.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Light.h) | Light node provides all the settings for positioning a light source, and controlling its type and color | + +## State commands + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::BindComputePipeline | [ComputePipeline.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ComputePipeline.h) | Bind the compute pipeline | +| vsg::BindGraphicsPipeline | [GraphicsPipeline.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/GraphicsPipeline.h) | Bind the graphics pipeline | +| vsg::BindDescriptorSet | [BindDescriptorSet.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/BindDescriptorSet.h) | Bind descriptor sets to current pipeline | +| vsg::PushConstants | [PushConstants.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/PushConstants.h) | Apply push constants using vkCmdPushConstants | +| vsg::StateSwitch | [StateSwitch.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/StateSwitch.h) | applies child state commands which pass mask test | + +## Shaders, Descriptor and Pipeline layout + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::ShaderModule etc. | [ShaderModule.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ShaderModule.h) | Settings for [vkShaderModule](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkShaderModuleCreateInfo.html) | +| vsg::ShaderStage | [ShaderStage.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ShaderStage.h) | Settings for [vkShaderStage](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineShaderStageCreateInfo.html) | +| vsg::DescriptorSetLayout | [DescriptorSetLayout.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorSetLayout.h) | Settings for [VkDescriptorSetLayout](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDescriptorSetLayoutCreateInfo.html) | +| vsg::PipelineLayout | [PipelineLayout.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/PipelineLayout.h) | Settings for [VkPipelineLayout](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineLayoutCreateInfo.html) | + +## Graphics pipeline state + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::ColorBlendState | [ColorBlendState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ColorBlendState.h) | [VkPipelineColorBlendStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineColorBlendStateCreateInfo.html) | +| vsg::DepthStencilState | [DepthStencilState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DepthStencilState.h) | [VkPipelineDepthStencilStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineDepthStencilStateCreateInfo.html)| +| vsg::InputAssemblyState| [InputAssemblyState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/InputAssemblyState.h) | [VkPipelineInputAssemblyStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineInputAssemblyStateCreateInfo.html) | +| vsg::DynamicState | [DynamicState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DynamicState.h) | [VkPipelineDynamicStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineDynamicStateCreateInfo.html) | +| vsg::MultisampleState | [MultisampleState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/MultisampleState.h) | [VkPipelineMultisampleStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineMultisampleStateCreateInfo.html) | +| vsg::RasterizationState | [RasterizationState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/RasterizationState.h) | [VkPipelineRasterizationStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineRasterizationStateCreateInfo.html) | +| vsg::TessellationState | [TessellationState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/TessellationState.h) | [VkPipelineTessellationStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineTessellationStateCreateInfo.html) | +| vsg::VertexInputState | [VertexInputState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/VertexInputState.h) | [VkPipelineVertexInputStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineVertexInputStateCreateInfo.html) | +| vsg::ViewportState| [ViewportState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ViewportState.h) | [VkPipelineViewportStateCreateInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineViewportStateCreateInfo.html) | + +## Descriptor state + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::BindDescriptorSet etc. | [BindDescriptorSet.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/BindDescriptorSet.h) | Encapsulates [vkCmdBindDescriptors](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/vkCmdBindDescriptorSets.html) | +| vsg::DescriptorSet | [DescriptorSet.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorSet.h) | Encapsulates [VkDescriptorSet](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDescriptorSetAllocateInfo.html)| +| vsg::Descriptor | [Descriptor.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/Descriptor.h) | Base class for [Descriptors](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html) | +| vsg::DescriptorBuffer | [DescriptorBuffer.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorBuffer.h) | Encapsulates [VkWriteDescriptorSet.pBufferInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html) | +| vsg::DescriptorImage | [DescriptorImage.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorImage.h) | Encapsulates [VkWriteDescriptorSet.pImageInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html) | +| vsg::DescriptorTexelBufferView | [DescriptorTexelBufferView.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorTexelBufferView.h) | Encapsulates [VkWriteDescriptorSet.pTexelBufferViews](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkWriteDescriptorSet.html) | +| vsg::Buffer | [Buffer.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/Buffer.h) | Encapsulates [VkBuffer](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkBufferCreateInfo.html) | +| vsg::material | [material.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/material.h) | Material vsg::Data types | +| vsg::BufferInfo | [BufferInfo.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/BufferInfo.h) | Encapsulates [VkDescriptorBufferInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDescriptorBufferInfo.html) | +| vsg::BufferView | [BufferView.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/BufferView.h) | Encapsulates [VkBufferView](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkBufferViewCreateInfo.html) | +| vsg::Sampler | [Sampler.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/Sampler.h) | Encapsulates [VkSampler](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkSamplerCreateInfo.html) | +| vsg::Image | [Image.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/Image.h) | Encapsulation of [VkImage](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImageCreateInfo.html) | +| vsg::ImageView | [ImageView.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ImageView.h) | Encapsulation of [VkImageView](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkImageViewCreateInfo.html) | +| vsg::ImageInfo | [ImageInfo.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ImageInfo.h) | Encapsulates [VkDescriptorImageInfo](https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkDescriptorImageInfo.html) | + +## General support classes + +| Class | Header | Functionality | +| --- | --- | --- | +| vsg::ResourceHints etc. | [ResourceHints.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ResourceHints.h) | Hints that can be assigned to a scene graph as user data to specify the GPU resources required. | +| vsg::ArrayState etc. | [ArrayState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ArrayState.h) | vsg::ArrayState base class for mapping vertex shader behavior on CPU | +| vsg::ViewDependentState etc. | [ViewDependentState.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/ViewDependentState.h) | View dependent state classes | +| vsg::QueryPool | [QueryPool.h](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/QueryPool.h) | Encapsulates VkQueryPool, used with vsg::BeginQuery etc. | + +Prev: [Commands](Commands.md)| Next : [Mesh Shaders](MeshShaders.md) + diff --git a/3_SceneGraph/index.md b/3_SceneGraph/index.md index 00f9a0b..482cd44 100644 --- a/3_SceneGraph/index.md +++ b/3_SceneGraph/index.md @@ -4,8 +4,13 @@ title: Scene Graph permalink: /scenegraph/ --- -**Sorry, not yet written.** +**Currently being written.** -7. Nodes - internal nodes of the scene graph -8. Geometry - meshes -9. State - shaders, textures, uniforms +At the heart of the VulkanSceneGraph is classes that make up the scene graph, all the classes and features discussed in the [Foundations](../2_Foundations/index.md) chapter provide the base from which these scene graph classes are built, and the subsequent [Application](../4_Application/index.md) chapter will provide the higher level integration to present the scene graph. This chapter will walk readers through the internal nodes of the scene graph, the commands that are recorded in Vulkan command buffers to do the work on the GPU, and the state that is used by those commands. + +1. [Nodes](Nodes.md) - internal nodes of the scene graph +2. [Commands](Commands.md) - Vulkan commands for operations on the GPU such as draw and compute +3. [State](State.md) - Vulkan state for setting data and programs on the GPU such as shaders, textures, uniforms +4. [Mesh Shaders](MeshShaders.md) - Vulkan mesh shader extensions nodes +5. [Ray Tracing](RayTracing.md) - Vulkan ray tracing extensions nodes +5. [osg2vsg](osg2vsg.md) - Porting between OpenSceneGraph and VulkanSceneGraph diff --git a/3_SceneGraph/osg2vsg.md b/3_SceneGraph/osg2vsg.md new file mode 100644 index 0000000..dc0f563 --- /dev/null +++ b/3_SceneGraph/osg2vsg.md @@ -0,0 +1,135 @@ +--- +layout: page +title: OpenSceneGraph to VulkanSceneGraph +permalink: /scenegraph/osg2vsg +--- + +## Smart pointers + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::ref_ptr`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/ref_ptr) | [`vsg::ref_ptr`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/ref_ptr.h) | | +| [`osg::observer_ptr`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/observer_ptr) | [`vsg::observer_ptr`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/observer_ptr.h) | + + +## Base classes + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::Referenced`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Referenced) | [`vsg::Object`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Object.h) | | +| [`osg::Object`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Object) | [`vsg::Object`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Object.h) | | +| [`META_Object`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Object), [`META_Node`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Node) | [`vsg::Inherit`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Inherit.h) | OSG uses C macros while VSG uses Curiously Recurring Template Pattern | +| | [`vsg::Allocator`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Allocator.h) | Only VSG has memory allocator. | + + +## Data classes + +| OSG | VSG | Notes | +| --- | --- | --- | +| | [`vsg::Data`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Data.h) | Base class with no OSG equivalent | +| [`osg::Image`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Image) | [`vsg::Value`, `vsg::Array`, `vsg::Array2D<>`, `vsg::Array3D`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/) | | +| [`osg::Uniform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Uniform) | `vsg::Value`, `vsg::Array`, `vsg::Array2D<>`, `vsg::Array3D` | | +| [`osg::Array`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Array) | [`vsg::Array`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Array.h) | | +| [`osg::IndexArray`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Array) | [`vsg::Array`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/core/Array.h) | | + +## Scene graph nodes + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::Node`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Node) | [`vsg::Node`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Node.h) | | +| [`osg::Group`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Group) | [`vsg::Group`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Group.h) | | +| [`osg::Switch`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Switch) | [`vsg::Switch`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Switch.h) | | +| [`osg::LOD`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/LOD) | [`vsg::LOD`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/LOD.h) | | +| [`osg::PagedLOD`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/PagedLOD) | [`vsg::PagedLOD`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/PagedLOD.h) | | +| [`osg::Transform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Transform) | [`vsg::Transform`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Transform.h) | Both base classes for providing model transforms | +| [`osg::MatrixTransform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/MatrixTransform) | [`vsg::MatrixTransform`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/MatrixTransform.h) | | +| [`osg::MatrixTransform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/MatrixTransform) | [`vsg::AbsoluteTransform`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/AbsoluteTransform.h) | osg::MatrixTransform::[setReferenceFrame(ABSOLUTE_RF)](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Transform#97) equivalent to vsg::AbsoluteTransform | +| [`osg::PositionAttitudeTransform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/PositionAttitudeTransform) | | No VSG equivalent | +| [`osg::AutoTransform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/AutoTransform) | | No VSG equivalent | +| [`osg::Billboard`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Billboard) | | No VSG equivalent - use instanced geometry and vertex shader. | + +## Geometry + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::Drawable`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Drawable) | [`vsg::Command`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Command.h) | | +| [`osg::Geometry`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Geometry) | [`vsg::Geometry`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/Geometry.h) | | +| [`osg::DrawArrays`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/PrimitiveSet#L221) | [`vsg::Draw`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Draw.h) | | +| [`osg::DrawElements`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/PrimitiveSet#L336) | [`vsg::DrawIndexed`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/DrawIndexed.h) | | +| | [`vsg::Commands`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/Commands.h) | No OSG equivalent. | +| | [`vsg::VertexDraw`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/VertexDraw) | No direct OSG equivalent, closest is osg::Geometry | +| | [`vsg::VertexIndexDraw`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/VertexIndexDraw.h) | No OSG equivalent, closest is osg::Geometry. | +| | [`vsg::BindVertexBuffers`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BindVerteBuffers.h) | No OSG equivalent. | +| | [`vsg::BindIndexBuffers`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/commands/BindIndexBuffers.h) | No OSG equivalent. | + +## State + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::StateSet`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/StateSet) | [`vsg::StateGroup`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/nodes/StateGroup.h) | osg::Group with an osg::StateSet is broadly similar to vsg::StateGroup | +| [`osg::StateAttribute`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/StateAttribute) | [`vsg::StateCommand`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/) | Both are state base classes, but only vaguely similar | +| [`osg::Texture`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Texture), osg::Texture1D, osg::Texture2D, osg::Texture3D, osg::TextureCubeMap, Texture2DArray | [`vsg::DescriptorImage`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorImage.h), vsg::ImageView, vsg::Image | No direct mapping but together fulfill the same role. | +| [`osg::Uniform`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Uniform) | [`vsg::DescriptorBuffer`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorBuffer.h) | | +| [`osg::Light`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Light.h), osg::LightSource | [`vsg::Light`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/state/DescriptorBuffer.h), vsg::AmbientLight, vsg::DirectionalLight, vsg;:PointLight, vsg::SpotLight | | + +## Text + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osgText::Font`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgText/Font) | [`vsg::Font`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/text/Font.h) | | +| [`osgText::Text`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgText/Text) | [`vsg::Text`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/text/Text.h) | | +| [`osgText::Text3D`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgText/Text3D) | | No VSG equivalent | +| | [`vsg::TextGroup`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/text/TextGroup.h) | No OSG equivalent for efficient rendering of large number of labels | + +## IO + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osgDB::readObjectFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ReadFile#L232) | [`vsg::read(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/read.h) | | +| [`osgDB::readNodeFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ReadFile#L308) | [`vsg::read_cast(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/read.h) | | +| [`osgDB::readImageFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ReadFile#L268) | [`vsg::read_cast(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/read.h) | | +| [`osgDB::writeObjectFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/WriteFile) | [`vsg::write(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/write.h) | | +| [`osgDB::writeNodeFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/WriteFile) | [`vsg::write(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/write.h) | | +| [`osgDB::writeImageFile(..)`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/WriteFile) | [`vsg::write(..)`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/write.h) | | +| [`osgDB::Options`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/Options) | [`vsg::Options`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/Options.h) | | +| [`osgDB::FileCache`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/FileCache) | [`vsg::Options::fileCache`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/Options.h#L75) | | +| [`osgDB::ObjectCache`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ObjectCache) | [`vsg::SharedObjects`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/utils/SharedObjects.h) | | +| [`osgDB::ReaderWriter`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ReaderWriter) | [`vsg::ReaderWriter`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/ReaderWriter.h) | | +| [`osgDB::Registry`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/Registry) | [`vsg::ObjectFactory`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/ObjectFactory.h) | | +| [`std::string & UTF8`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/ConvertUTF8) | [`vsg::Path`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/Path.h) | OSG must be compiled with OSG_USE_UTF8_FILENAME, vsg::Path works like std::filesystem::path | +| [`osgDB::DatabasePager`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgDB/DatabasePager) | [`vsg::DatabasePager`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/io/DatabasePager.h) | | + +## Application + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`osg::Camera`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osg/Camera.h) | [`vsg::Camera`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/Camear.h) | | +| [`osgViewer::View`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgViewer/View.h) | [`vsg::View`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/View.h) | | +| [`osgViewer::Viewer`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgViewer/Viewer.h) | [`vsg::Viewer`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/Viewer.h) | | +| [`osgViewer::CompositeViewer`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgViewer/CompositeViewer.h) | [`vsg::Viewer`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/Viewer.h) | | +| [`osgGA::TrackballManipulator`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/osgGA/TrackballManipulator) | [`vsg::Trackball`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/Trackball.h) | | +| | [`vsg::CommandGraph`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/CommandGraph.h) | No OSG equivalent | +| | [`vsg::RenderGraph`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/RenderGraph.h) | No OSG equivalent | +| | [`vsg::RecordAndSubmitTask`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/RecordAndSubmitTask.h) | No OSG equivalent | +| | [`vsg::ExecuteCommands`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/app/ExecuteCommands.h) | No OSG equivalent | + +## Threading + +| OSG | VSG | Notes | +| --- | --- | --- | +| [`OpenThreads::Thread`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Thread) | std::thread | | +| [`OpenThreads::Mutex`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Mutex) | std::mutex| | +| [`OpenThreads::ScopedLock`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Block.h) | std::lock_guard | | +| [`OpenThreads::Atomic`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Atomic) | std::atomic | | +| [`OpenThreads::Condition`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Condition) | std::condition_variable | | +| [`OpenThreads::Barrier`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Barrier) | [`vsg::Barrier`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/Barrier.h) | | +| [`OpenThreads::Block`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Block) | [`vsg::Latch`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/Latch.h) | | +| [`OpenThreads::Affinity`](https://github.com/openscenegraph/OpenSceneGraph/blob/master/include/OpenThreads/Affinity) | [`vsg::Affinity`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/Affinity.h) | | +| [`osg::OperationThread`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/osg/OperationThread) | [`vsg::OperationThread`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/OperationThread.h) | | +| [`osg::OperationThread`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/osg/OperationThread) | [`vsg::OperationQueue`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/OperationQueue.h) | | +| [`osg::Operation`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/osg/OperationThread) | [`vsg::Operation`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/OperationQueue.h) | | +| | [`vsg::ActivityStatus`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/ActivityStatus.h) | No OSG equivalent, used to cooperatively release barriers & blocks. | +| | [`vsg::FrameBlock`](https://github.com/vsg-dev/VulkanSceneGraph/blob/master/include/vsg/threading/FrameBlock.h) | No direct OSG equivalent, loosely OpenThreads::Block. | + +Prev : [Ray Tracing](RayTracing.md) | Next : [Next Chapter : Application](../4_Application/index.md) + diff --git a/5_DevelopingSkills/index.md b/5_DevelopingSkills/index.md index 7407192..22fbfb1 100644 --- a/5_DevelopingSkills/index.md +++ b/5_DevelopingSkills/index.md @@ -7,4 +7,4 @@ permalink: /skills/ **Sorry, not yet written.** 13. Trouble Shooting - debugging VulkanSceneGraph applications -14. Optimizaton - how to improve performance & low power consumption +14. Optimization - how to improve performance & lower power consumption diff --git a/index.md b/index.md index 489a055..a805eba 100644 --- a/index.md +++ b/index.md @@ -7,21 +7,21 @@ layout: home **CURRENTLY IN DEVELOPMENT: expect missing sections and rough and ready state.** -The goal of this tutorial is to teach developers how to use the [VulkanSceneGraph](https://github.com/vsg-dev/VulkanSceneGraph) effectively in their graphics and compute applications. The tutorial assumes developers have prior knowledge of using CMake and C++ to build and write applications. Knowledge of scene graphs, real-time graphics and Vulkan are not assumed, though teaching real-time graphics and Vulkan at depth is beyond the scope of this tutorial, links to 3rd party resources for further learning will be provided. +The goal of this tutorial is to teach developers how to use the [VulkanSceneGraph](https://github.com/vsg-dev/VulkanSceneGraph) effectively in their graphics and compute applications. The tutorial assumes developers have prior knowledge of using CMake and C++ to build and write applications. Knowledge of scene graphs, real-time graphics and Vulkan are not assumed, though teaching real-time graphics and Vulkan at depth is beyond the scope of this tutorial, links to 3rd party resources for further learning will be provided. -Each chapter of the tutorial is coupled with exercises so that developers can learn about each topic then test out what they have learned. The topics covered are: +Each chapter of the tutorial is coupled with exercises so that developers can learn about each topic then test out what they have learned. The topics covered are: -1. [Setting The Scene](1_SettingTheScene/index.md) **First Draft** -We introduce you to world of scene graphs with a brief tour of low and high-level APIs from IrisGL & Inventor to Vulkan & VulkanSceneGraph. The chapter then turns to the software design and performance principles used in the development of the VulkanSceneGraph, the ecosystem building up around the project, high-level features and conventions you'll get with the core VulkanSceneGraph library and wraps up with how to build the software and run the first exercise - a scene graph take on Hello World. +1. [Setting The Scene](1_SettingTheScene/index.md) **First Draft** +We introduce you to the world of scene graphs with a brief tour of low and high-level APIs from IrisGL & Inventor to Vulkan & VulkanSceneGraph. The chapter then turns to the software design and performance principles used in the development of the VulkanSceneGraph, the ecosystem building up around the project, high-level features and conventions you'll get with the core VulkanSceneGraph library and wraps up with how to build the software and run the first exercise - a scene graph take on Hello World. -2. [Foundations](2_Foundations/index.md) **Currently being written.** +2. [Foundations](2_Foundations/index.md) **First Draft** This chapter covers the foundational base classes, memory management, maths and IO support that the rest of the scene graph functionality is built upon. -3. [Scene Graph](3_SceneGraph/index.md) **To be written** +3. [Scene Graph](3_SceneGraph/index.md) **Currently being written** This chapter introduces the scene graph classes - the internal nodes through to the geometry and state. -4. [Application](4_Application/index.md) **To be written** +4. [Application](4_Application/index.md) **To be written** This chapter focuses on application level classes - the viewer, windows, views, cameras, event handling, rendering loop and threading. -5. [Developing Skills](5_DevelopingSkills/index.md) **To be written** +5. [Developing Skills](5_DevelopingSkills/index.md) **To be written** The final chapter wraps up with guidance on trouble shooting and debugging VulkanSceneGraph applications, through to how to improve performance & lower power consumption.