├── .gitignore ├── 3rdparty ├── CMakeLists.txt ├── spirv_reflect │ ├── CMakeLists.txt │ ├── README.md │ ├── include │ │ └── spirv │ │ │ └── unified1 │ │ │ └── spirv.h │ ├── spirv_reflect.c │ └── spirv_reflect.h ├── stb │ ├── CMakeLists.txt │ ├── libstb.c │ ├── stb_image.h │ └── stb_image_write.h ├── vma │ ├── CMakeLists.txt │ ├── LICENSE.txt │ ├── README.md │ ├── vk_mem_alloc.cpp │ └── vk_mem_alloc.h └── volk │ ├── CMakeLists.txt │ ├── README.md │ ├── volk.c │ └── volk.h ├── CMakeLists.txt ├── LICENSE ├── README.md ├── apps ├── CMakeLists.txt ├── quartz │ ├── CMakeLists.txt │ ├── imagewriter.cpp │ ├── imagewriter.h │ ├── main.cpp │ ├── renderwindow.cpp │ ├── renderwindow.h │ ├── resources │ │ ├── appicon_win32.ico │ │ └── quartz.rc │ └── version.h └── scene2qml │ ├── CMakeLists.txt │ ├── exporter.cpp │ ├── exporter.h │ ├── importer.cpp │ ├── importer.h │ ├── main.cpp │ └── scene.h ├── cmake └── Findassimp.cmake ├── doc ├── helloworld.jpg └── renders.jpg ├── examples ├── CMakeLists.txt ├── assets │ ├── monkey.obj │ └── plane.obj ├── raytrace-cpp │ ├── CMakeLists.txt │ ├── main.cpp │ └── raytrace-cpp.qrc └── raytrace-qml │ ├── CMakeLists.txt │ ├── main.cpp │ ├── main.qml │ └── raytrace-qml.qrc ├── include ├── Qt3DRaytrace │ ├── qabstracttexture.h │ ├── qcamera.h │ ├── qcameralens.h │ ├── qcolorspace.h │ ├── qdistantlight.h │ ├── qgeometry.h │ ├── qgeometrydata.h │ ├── qgeometryfactory.h │ ├── qgeometryrenderer.h │ ├── qimagedata.h │ ├── qmaterial.h │ ├── qmesh.h │ ├── qraytraceaspect.h │ ├── qrenderimage.h │ ├── qrendersettings.h │ ├── qt3draytrace_global.h │ ├── qt3draytracecontext.h │ ├── qtexture.h │ ├── qtextureimage.h │ └── qtextureimagefactory.h └── Qt3DRaytraceExtras │ ├── qfirstpersoncameracontroller.h │ ├── qt3dquickwindow.h │ ├── qt3draytraceextras_global.h │ └── qt3dwindow.h └── src ├── CMakeLists.txt ├── extras ├── CMakeLists.txt ├── qfirstpersoncameracontroller.cpp ├── qfirstpersoncameracontroller_p.h ├── qt3dquickwindow.cpp ├── qt3dquickwindow_p.h ├── qt3draytraceextras_global_p.h ├── qt3dwindow.cpp └── qt3dwindow_p.h ├── qml ├── CMakeLists.txt ├── quick3draytrace │ ├── CMakeLists.txt │ ├── qmldir │ ├── qtquick3draytraceplugin.cpp │ └── qtquick3draytraceplugin.h └── quick3draytraceextras │ ├── CMakeLists.txt │ ├── qmldir │ ├── qtquick3draytraceextrasplugin.cpp │ └── qtquick3draytraceextrasplugin.h └── raytrace ├── CMakeLists.txt ├── backend ├── abstractrenderer_p.h ├── abstracttexture.cpp ├── abstracttexture_p.h ├── backendnode.cpp ├── backendnode_p.h ├── cameralens.cpp ├── cameralens_p.h ├── distantlight.cpp ├── distantlight_p.h ├── entity.cpp ├── entity_p.h ├── geometry.cpp ├── geometry_p.h ├── geometryrenderer.cpp ├── geometryrenderer_p.h ├── handles_p.h ├── managers_p.h ├── material.cpp ├── material_p.h ├── rendersettings.cpp ├── rendersettings_p.h ├── textureimage.cpp ├── textureimage_p.h ├── transform.cpp ├── transform_p.h └── types_p.h ├── frontend ├── qabstracttexture.cpp ├── qabstracttexture_p.h ├── qcamera.cpp ├── qcamera_p.h ├── qcameralens.cpp ├── qcameralens_p.h ├── qdistantlight.cpp ├── qdistantlight_p.h ├── qgeometry.cpp ├── qgeometry_p.h ├── qgeometryrenderer.cpp ├── qgeometryrenderer_p.h ├── qmaterial.cpp ├── qmaterial_p.h ├── qmesh.cpp ├── qmesh_p.h ├── qrendersettings.cpp ├── qrendersettings_p.h ├── qtexture.cpp ├── qtexture_p.h ├── qtextureimage.cpp └── qtextureimage_p.h ├── io ├── common_p.h ├── defaultimageimporter.cpp ├── defaultimageimporter_p.h ├── defaultmeshimporter.cpp ├── defaultmeshimporter_p.h ├── imageimporter_p.h └── meshimporter_p.h ├── jobs ├── loadgeometryjob.cpp ├── loadgeometryjob_p.h ├── loadtexturejob.cpp ├── loadtexturejob_p.h ├── updateworldtransformjob.cpp └── updateworldtransformjob_p.h ├── qraytraceaspect.cpp ├── qraytraceaspect_p.h ├── qt3draytrace_global_p.h ├── qt3draytracecontext.cpp ├── renderers ├── CMakeLists.txt └── vulkan │ ├── CMakeLists.txt │ ├── commandbuffer.cpp │ ├── commandbuffer.h │ ├── descriptors.h │ ├── device.cpp │ ├── device.h │ ├── geometry.h │ ├── glsl.h │ ├── initializers.h │ ├── jobs │ ├── buildgeometryjob.cpp │ ├── buildgeometryjob.h │ ├── buildscenetlasjob.cpp │ ├── buildscenetlasjob.h │ ├── destroyexpiredresourcesjob.cpp │ ├── destroyexpiredresourcesjob.h │ ├── updateemittersjob.cpp │ ├── updateemittersjob.h │ ├── updateinstancebufferjob.cpp │ ├── updateinstancebufferjob.h │ ├── updatematerialsjob.cpp │ ├── updatematerialsjob.h │ ├── updaterenderparametersjob.cpp │ ├── updaterenderparametersjob.h │ ├── uploadtexturejob.cpp │ └── uploadtexturejob.h │ ├── managers │ ├── cameramanager.cpp │ ├── cameramanager.h │ ├── commandbuffermanager.cpp │ ├── commandbuffermanager.h │ ├── descriptormanager.cpp │ ├── descriptormanager.h │ ├── scenemanager.cpp │ ├── scenemanager.h │ └── sceneresourceset.h │ ├── pipeline │ ├── computepipeline.cpp │ ├── computepipeline.h │ ├── graphicspipeline.cpp │ ├── graphicspipeline.h │ ├── pipeline.cpp │ ├── pipeline.h │ ├── raytracingpipeline.cpp │ └── raytracingpipeline.h │ ├── renderer.cpp │ ├── renderer.h │ ├── resourcebarrier.h │ ├── services │ ├── frameadvanceservice.cpp │ └── frameadvanceservice.h │ ├── shadermodule.cpp │ ├── shadermodule.h │ ├── shaders │ ├── .gitignore │ ├── compile.py │ ├── display.frag.glsl │ ├── display.vert.glsl │ ├── lib │ │ ├── bindings.glsl │ │ ├── bsdf.glsl │ │ ├── common.glsl │ │ ├── geometry.glsl │ │ ├── resources.glsl │ │ ├── sampling.glsl │ │ ├── shared.glsl │ │ └── xoroshiro64s.glsl │ ├── pathtrace.rchit.glsl │ ├── pathtrace.rgen.glsl │ ├── pathtrace.rmiss.glsl │ ├── queryemission.rchit.glsl │ ├── queryemission.rmiss.glsl │ ├── queryvisibility.rchit.glsl │ └── queryvisibility.rmiss.glsl │ ├── vkcommon.h │ └── vkresources.h └── utility └── movingaverage.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.user 2 | 3 | -------------------------------------------------------------------------------- /3rdparty/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | set(CMAKE_POSITION_INDEPENDENT_CODE ON) 4 | set(QUARTZ_3RDPARTY ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) 5 | 6 | add_subdirectory(spirv_reflect) 7 | add_subdirectory(stb) 8 | add_subdirectory(volk) 9 | add_subdirectory(vma) 10 | -------------------------------------------------------------------------------- /3rdparty/spirv_reflect/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(spirv_reflect) 3 | 4 | find_package(Vulkan REQUIRED) 5 | 6 | add_library(spirv_reflect STATIC spirv_reflect.c spirv_reflect.h) 7 | target_include_directories(spirv_reflect PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 8 | target_link_libraries(spirv_reflect Vulkan::Vulkan) 9 | -------------------------------------------------------------------------------- /3rdparty/stb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(libstb) 3 | 4 | add_library(stb STATIC 5 | libstb.c 6 | stb_image.h 7 | stb_image_write.h 8 | ) 9 | target_include_directories(stb PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 10 | -------------------------------------------------------------------------------- /3rdparty/stb/libstb.c: -------------------------------------------------------------------------------- 1 | #define STB_IMAGE_IMPLEMENTATION 2 | #define STB_IMAGE_WRITE_IMPLEMENTATION 3 | #include "stb_image.h" 4 | #include "stb_image_write.h" 5 | -------------------------------------------------------------------------------- /3rdparty/vma/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(vma) 3 | 4 | find_package(Vulkan REQUIRED) 5 | 6 | add_library(vma STATIC vk_mem_alloc.cpp vk_mem_alloc.h) 7 | target_include_directories(vma PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 8 | target_link_libraries(vma Vulkan::Vulkan) 9 | -------------------------------------------------------------------------------- /3rdparty/vma/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017-2018 Advanced Micro Devices, Inc. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /3rdparty/vma/vk_mem_alloc.cpp: -------------------------------------------------------------------------------- 1 | #define VMA_IMPLEMENTATION 2 | #define VMA_STATIC_VULKAN_FUNCTIONS 0 3 | #include "vk_mem_alloc.h" 4 | -------------------------------------------------------------------------------- /3rdparty/volk/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(volk) 3 | 4 | find_package(Vulkan REQUIRED) 5 | 6 | add_library(volk STATIC volk.c volk.h) 7 | target_include_directories(volk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) 8 | target_link_libraries(volk Vulkan::Vulkan) 9 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | project(Quartz) 3 | 4 | option(BUILD_SHARED_LIBS "Build shared libraries" ON) 5 | option(BUILD_APPS "Build the standalone renderer & supplemental tools" ON) 6 | option(BUILD_EXAMPLES "Build example programs" ON) 7 | 8 | option(DUMP_QML_TYPEINFO "Dump QML type information for use in QtCreator" OFF) 9 | 10 | set(QTDIR "$ENV{QTDIR}" CACHE STRING "Path to Qt SDK") 11 | 12 | set(CMAKE_INCLUDE_CURRENT_DIR ON) 13 | set(CMAKE_AUTOMOC ON) 14 | set(CMAKE_AUTORCC ON) 15 | 16 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") 17 | set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "${QTDIR}/lib/cmake") 18 | 19 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DQUARTZ_DEBUG") 20 | 21 | add_subdirectory(3rdparty) 22 | add_subdirectory(src) 23 | 24 | if(BUILD_APPS) 25 | add_subdirectory(apps) 26 | endif() 27 | if(BUILD_EXAMPLES) 28 | add_subdirectory(examples) 29 | endif() 30 | 31 | set(QML_IMPORT_PATH "${PROJECT_BINARY_DIR}/qml") 32 | -------------------------------------------------------------------------------- /apps/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(quartz) 2 | add_subdirectory(scene2qml) 3 | -------------------------------------------------------------------------------- /apps/quartz/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | set(APP_NAME "quartz") 4 | 5 | find_package(Qt5 COMPONENTS Core Gui Widgets Qml REQUIRED) 6 | 7 | add_executable(${APP_NAME} 8 | main.cpp 9 | renderwindow.cpp 10 | renderwindow.h 11 | imagewriter.cpp 12 | imagewriter.h 13 | version.h 14 | ) 15 | 16 | if(WIN32) 17 | target_sources(${APP_NAME} PRIVATE resources/quartz.rc) 18 | endif() 19 | 20 | target_compile_features(${APP_NAME} PRIVATE cxx_std_14) 21 | target_include_directories(${APP_NAME} PRIVATE ${QUARTZ_3RDPARTY}) 22 | target_link_libraries(${APP_NAME} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Qml Qt3DRaytrace Qt3DRaytraceExtras stb) 23 | -------------------------------------------------------------------------------- /apps/quartz/imagewriter.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | class ImageWriter : public QThread 15 | { 16 | Q_OBJECT 17 | public: 18 | explicit ImageWriter(QObject *parent); 19 | 20 | void setOutputPath(const QString &path); 21 | void setImage(const Qt3DRaytrace::QImageDataPtr &image); 22 | void setQuality(int quality); 23 | 24 | private: 25 | void run() override; 26 | 27 | QString m_outputPath; 28 | Qt3DRaytrace::QImageDataPtr m_image; 29 | int m_quality; 30 | }; 31 | -------------------------------------------------------------------------------- /apps/quartz/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "renderwindow.h" 13 | #include "version.h" 14 | 15 | namespace Config { 16 | static constexpr int DefaultViewportWidth = 1280; 17 | static constexpr int DefaultViewportHeight = 720; 18 | } // Config 19 | 20 | static void parseOptions(int &viewportWidth, int &viewportHeight, QString &sceneFilePath) 21 | { 22 | const QString description = QString("%1 %2\n%3\n%4") 23 | .arg(ApplicationDescription) 24 | .arg(ApplicationVersion) 25 | .arg(ApplicationCopyright) 26 | .arg(ApplicationUrl); 27 | 28 | QCommandLineParser parser; 29 | parser.setApplicationDescription(description); 30 | parser.addHelpOption(); 31 | parser.addVersionOption(); 32 | 33 | QCommandLineOption widthOption({"x", "sizex", "width"}, "Initial viewport width.", "px", 34 | QString::number(Config::DefaultViewportWidth)); 35 | QCommandLineOption heightOption({"y", "sizey", "height"}, "Initial viewport height.", "px", 36 | QString::number(Config::DefaultViewportHeight)); 37 | parser.addOptions({widthOption, heightOption}); 38 | parser.addPositionalArgument("scene", "QML scene file path"); 39 | 40 | parser.process(*QApplication::instance()); 41 | viewportWidth = parser.value(widthOption).toInt(); 42 | viewportHeight = parser.value(heightOption).toInt(); 43 | if(viewportWidth <= 0 || viewportHeight <= 0) { 44 | QTextStream(stderr) << "Error: Invalid viewport dimensions\n"; 45 | parser.showHelp(1); 46 | } 47 | 48 | if(parser.positionalArguments().size() > 0) { 49 | sceneFilePath = parser.positionalArguments().at(0); 50 | } 51 | } 52 | 53 | int main(int argc, char *argv[]) 54 | { 55 | QApplication app(argc, argv); 56 | QApplication::setApplicationName(ApplicationName); 57 | QApplication::setApplicationVersion(ApplicationVersion); 58 | 59 | int viewportWidth; 60 | int viewportHeight; 61 | QString sceneFilePath; 62 | parseOptions(viewportWidth, viewportHeight, sceneFilePath); 63 | 64 | QTextStream(stdout) << ApplicationDescription << " " 65 | << ApplicationVersion << "\n"; 66 | 67 | QScopedPointer vulkanInstance(RenderWindow::createDefaultVulkanInstance()); 68 | if(!vulkanInstance) { 69 | return 1; 70 | } 71 | 72 | RenderWindow window; 73 | window.setWidth(viewportWidth); 74 | window.setHeight(viewportHeight); 75 | window.setVulkanInstance(vulkanInstance.get()); 76 | 77 | if(sceneFilePath.length() > 0) { 78 | if(!window.setSourceFile(sceneFilePath)) { 79 | return 1; 80 | } 81 | } 82 | else { 83 | if(!window.requestSourceFile()) { 84 | return 1; 85 | } 86 | } 87 | 88 | window.show(); 89 | 90 | return app.exec(); 91 | } 92 | -------------------------------------------------------------------------------- /apps/quartz/renderwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | class RenderWindow : public Qt3DRaytraceExtras::Quick::Qt3DQuickWindow 16 | { 17 | Q_OBJECT 18 | public: 19 | RenderWindow(); 20 | 21 | static QVulkanInstance *createDefaultVulkanInstance(); 22 | 23 | bool requestSourceFile(); 24 | bool setSourceFile(const QString &path); 25 | void setSceneName(const QString &name); 26 | 27 | bool requestSaveImage(); 28 | bool saveImage(const QString &path); 29 | 30 | protected: 31 | void keyPressEvent(QKeyEvent *event) override; 32 | 33 | private slots: 34 | void updateTitle(); 35 | void imageReady(Qt3DRaytrace::QRenderImage type, Qt3DRaytrace::QImageDataPtr image); 36 | 37 | private: 38 | QString m_sceneName; 39 | QString m_saveImageRequestPath; 40 | }; 41 | -------------------------------------------------------------------------------- /apps/quartz/resources/appicon_win32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nadrin/Quartz/1f07a9b5cf195b8328ea4a775809acebed121e71/apps/quartz/resources/appicon_win32.ico -------------------------------------------------------------------------------- /apps/quartz/resources/quartz.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "appicon_win32.ico" 2 | -------------------------------------------------------------------------------- /apps/quartz/version.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | static const QString ApplicationName("Quartz"); 12 | static const QString ApplicationDescription("Quartz Standalone Renderer"); 13 | static const QString ApplicationCopyright("(c) 2018-2019 Michal Siejak "); 14 | static const QString ApplicationUrl("https://github.com/Nadrin/Quartz"); 15 | static const QString ApplicationVersion("1.0.1"); 16 | -------------------------------------------------------------------------------- /apps/scene2qml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | set(APP_NAME "scene2qml") 4 | 5 | find_package(Qt5 COMPONENTS Core REQUIRED) 6 | find_package(assimp REQUIRED) 7 | 8 | add_executable(${APP_NAME} 9 | main.cpp 10 | importer.cpp 11 | importer.h 12 | exporter.cpp 13 | exporter.h 14 | scene.h 15 | ) 16 | 17 | target_include_directories(${APP_NAME} 18 | PRIVATE ${QUARTZ_3RDPARTY} 19 | PRIVATE ${assimp_INCLUDE_DIRS} 20 | ) 21 | 22 | target_compile_features(${APP_NAME} PRIVATE cxx_std_14) 23 | target_link_libraries(${APP_NAME} Qt5::Core ${assimp_LIBRARIES}) 24 | -------------------------------------------------------------------------------- /apps/scene2qml/importer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "scene.h" 15 | 16 | #include 17 | #include 18 | 19 | class Importer 20 | { 21 | public: 22 | Importer(); 23 | 24 | void setImportFlag(unsigned int flag); 25 | bool importScene(const QString &path); 26 | 27 | const Scene &scene() const 28 | { 29 | return m_scene; 30 | } 31 | 32 | private: 33 | Entity *processScene(const aiScene *scene); 34 | Entity *processSceneNode(const aiNode *node); 35 | 36 | int processTextureReference(const aiMaterial *material, aiTextureType type); 37 | bool processMeshReference(unsigned int meshIndex, Entity *entity); 38 | 39 | Scene m_scene; 40 | Assimp::Importer m_importer; 41 | QMap m_texturesByPath; 42 | unsigned int m_importFlags; 43 | }; 44 | -------------------------------------------------------------------------------- /apps/scene2qml/scene.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | struct Vector3D 15 | { 16 | float x = 0.0f; 17 | float y = 0.0f; 18 | float z = 0.0f; 19 | 20 | bool isNull() const 21 | { 22 | return qFuzzyIsNull(x) && qFuzzyIsNull(y) && qFuzzyIsNull(z); 23 | } 24 | bool isOne() const 25 | { 26 | return qFuzzyCompare(x, 1.0f) && qFuzzyCompare(y, 1.0f) && qFuzzyCompare(z, 1.0f); 27 | } 28 | bool componentsEqual() const 29 | { 30 | return qFuzzyCompare(x, y) && qFuzzyCompare(x, z); 31 | } 32 | }; 33 | 34 | struct Color 35 | { 36 | float r = 0.0f; 37 | float g = 0.0f; 38 | float b = 0.0f; 39 | 40 | bool isBlack() const 41 | { 42 | return qFuzzyIsNull(r) && qFuzzyIsNull(g) && qFuzzyIsNull(b); 43 | } 44 | float normalizeIntensity() 45 | { 46 | float intensity = std::max({r, g, b}); 47 | if(intensity > 1.0f) { 48 | r /= intensity; 49 | g /= intensity; 50 | b /= intensity; 51 | return intensity; 52 | } 53 | else { 54 | return 1.0f; 55 | } 56 | } 57 | }; 58 | 59 | struct Transform 60 | { 61 | Vector3D translation; 62 | Vector3D rotation; 63 | Vector3D scale = {1.0f, 1.0f, 1.0f}; 64 | 65 | bool isIdentity() const 66 | { 67 | return translation.isNull() && rotation.isNull() && scale.isOne(); 68 | } 69 | }; 70 | 71 | struct Component 72 | { 73 | QString name; 74 | unsigned int refcount = 0; 75 | }; 76 | 77 | struct MeshComponent : Component 78 | { 79 | const aiMesh *mesh = nullptr; 80 | }; 81 | 82 | struct MaterialComponent : Component 83 | { 84 | Color albedo = {1.0f, 1.0f, 1.0f}; 85 | Color emission; 86 | float emissionIntensity = 0.0f; 87 | float roughness = 1.0f; 88 | float metalness = 0.0f; 89 | int albedoTextureIndex = -1; 90 | int roughnessTextureIndex = -1; 91 | int metalnessTextureIndex = -1; 92 | }; 93 | 94 | struct TextureComponent final : Component 95 | { 96 | QString format; 97 | unsigned int width = 0; 98 | unsigned int height = 0; 99 | const unsigned char *data = nullptr; 100 | }; 101 | 102 | struct Entity 103 | { 104 | ~Entity() { qDeleteAll(children); } 105 | 106 | QString name; 107 | Entity *parent = nullptr; 108 | QVector children; 109 | Transform transform; 110 | int meshComponentIndex = -1; 111 | int materialComponentIndex = -1; 112 | }; 113 | 114 | struct Scene 115 | { 116 | ~Scene() { delete root; } 117 | 118 | Entity *root = nullptr; 119 | QVector meshes; 120 | QVector materials; 121 | QVector textures; 122 | }; 123 | -------------------------------------------------------------------------------- /cmake/Findassimp.cmake: -------------------------------------------------------------------------------- 1 | if(CMAKE_SIZEOF_VOID_P EQUAL 8) 2 | set(ASSIMP_ARCHITECTURE "x64") 3 | elseif(CMAKE_SIZEOF_VOID_P EQUAL 4) 4 | set(ASSIMP_ARCHITECTURE "win32") 5 | endif(CMAKE_SIZEOF_VOID_P EQUAL 8) 6 | 7 | if(WIN32) 8 | set(ASSIMP_ROOT_DIR "C:/Program Files/Assimp" CACHE PATH "ASSIMP root directory") 9 | 10 | # Find path of each library 11 | find_path(assimp_INCLUDE_DIRS 12 | NAMES 13 | assimp/anim.h 14 | HINTS 15 | ${ASSIMP_ROOT_DIR}/include 16 | ) 17 | 18 | if(MSVC12) 19 | set(ASSIMP_MSVC_VERSION "vc120") 20 | elseif(MSVC14) 21 | set(ASSIMP_MSVC_VERSION "vc140") 22 | endif(MSVC12) 23 | 24 | if(MSVC12 OR MSVC14) 25 | 26 | find_path(ASSIMP_LIBRARY_DIR 27 | NAMES 28 | assimp-${ASSIMP_MSVC_VERSION}-mt.lib 29 | HINTS 30 | ${ASSIMP_ROOT_DIR}/lib/${ASSIMP_ARCHITECTURE} 31 | ) 32 | 33 | find_path(ASSIMP_BINARY_DIR 34 | NAMES 35 | assimp-${ASSIMP_MSVC_VERSION}-mt.dll 36 | HINTS 37 | ${ASSIMP_ROOT_DIR}/bin/${ASSIMP_ARCHITECTURE} 38 | ) 39 | 40 | find_library( 41 | assimp_LIBRARIES 42 | NAMES assimp-${ASSIMP_MSVC_VERSION}-mt.lib 43 | PATHS ${ASSIMP_LIBRARY_DIR} 44 | ) 45 | 46 | endif() 47 | 48 | else(WIN32) 49 | find_package(PkgConfig REQUIRED) 50 | pkg_check_modules(assimp REQUIRED assimp) 51 | endif(WIN32) 52 | 53 | if (assimp_INCLUDE_DIRS AND assimp_LIBRARIES) 54 | SET(assimp_FOUND TRUE) 55 | ENDIF (assimp_INCLUDE_DIRS AND assimp_LIBRARIES) 56 | 57 | if (assimp_FOUND) 58 | if (NOT assimp_FIND_QUIETLY) 59 | message(STATUS "Found asset importer library: ${assimp_LIBRARIES}") 60 | endif (NOT assimp_FIND_QUIETLY) 61 | else (assimp_FOUND) 62 | if (assimp_FIND_REQUIRED) 63 | message(FATAL_ERROR "Could not find asset importer library") 64 | endif (assimp_FIND_REQUIRED) 65 | endif (assimp_FOUND) 66 | -------------------------------------------------------------------------------- /doc/helloworld.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nadrin/Quartz/1f07a9b5cf195b8328ea4a775809acebed121e71/doc/helloworld.jpg -------------------------------------------------------------------------------- /doc/renders.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Nadrin/Quartz/1f07a9b5cf195b8328ea4a775809acebed121e71/doc/renders.jpg -------------------------------------------------------------------------------- /examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(raytrace-cpp) 2 | add_subdirectory(raytrace-qml) 3 | -------------------------------------------------------------------------------- /examples/assets/plane.obj: -------------------------------------------------------------------------------- 1 | # Blender v2.80 (sub 45) OBJ File: '' 2 | # www.blender.org 3 | v -1.000000 0.000000 1.000000 4 | v 1.000000 0.000000 1.000000 5 | v -1.000000 0.000000 -1.000000 6 | v 1.000000 0.000000 -1.000000 7 | vt 0.000000 0.000000 8 | vt 1.000000 0.000000 9 | vt 1.000000 1.000000 10 | vt 0.000000 1.000000 11 | vn 0.0000 1.0000 0.0000 12 | s off 13 | f 1/1/1 2/2/1 4/3/1 3/4/1 14 | -------------------------------------------------------------------------------- /examples/raytrace-cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | set(APP_NAME "raytrace-cpp") 4 | 5 | find_package(Qt5 COMPONENTS Core Gui 3DCore REQUIRED) 6 | 7 | add_executable(${APP_NAME} main.cpp raytrace-cpp.qrc) 8 | 9 | target_compile_features(${APP_NAME} PRIVATE cxx_std_14) 10 | target_include_directories(${APP_NAME} PRIVATE ${QUARTZ_3RDPARTY}) 11 | target_link_libraries(${APP_NAME} Qt5::Core Qt5::Gui Qt5::3DCore Qt3DRaytrace Qt3DRaytraceExtras volk) 12 | -------------------------------------------------------------------------------- /examples/raytrace-cpp/raytrace-cpp.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ../assets/plane.obj 5 | ../assets/monkey.obj 6 | 7 | 8 | -------------------------------------------------------------------------------- /examples/raytrace-qml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.8) 2 | 3 | set(APP_NAME "raytrace-qml") 4 | 5 | find_package(Qt5 COMPONENTS Core Gui 3DCore REQUIRED) 6 | 7 | add_executable(${APP_NAME} main.cpp raytrace-qml.qrc) 8 | 9 | target_compile_features(${APP_NAME} PRIVATE cxx_std_14) 10 | target_include_directories(${APP_NAME} PRIVATE ${QUARTZ_3RDPARTY}) 11 | target_link_libraries(${APP_NAME} Qt5::Core Qt5::Gui Qt5::3DCore Qt3DRaytrace Qt3DRaytraceExtras volk) 12 | -------------------------------------------------------------------------------- /examples/raytrace-qml/main.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | int main(int argc, char **argv) 12 | { 13 | QGuiApplication app(argc, argv); 14 | 15 | QVulkanInstance vulkanInstance; 16 | vulkanInstance.setApiVersion(QVersionNumber(1, 1)); 17 | if(!vulkanInstance.create()) { 18 | qFatal("Failed to create Vulkan instance: %x", vulkanInstance.errorCode()); 19 | } 20 | 21 | Qt3DRaytraceExtras::Quick::Qt3DQuickWindow window; 22 | window.setVulkanInstance(&vulkanInstance); 23 | window.setSource(QUrl("qrc:/main.qml")); 24 | window.setWidth(1024); 25 | window.setHeight(1024); 26 | window.show(); 27 | 28 | return app.exec(); 29 | } 30 | -------------------------------------------------------------------------------- /examples/raytrace-qml/main.qml: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | import QtQuick 2.2 8 | import Qt3D.Core 2.0 9 | import Qt3D.Input 2.0 10 | import Qt3D.Raytrace 1.0 11 | import Qt3D.RaytraceExtras 1.0 12 | 13 | Entity { 14 | id: root 15 | components: [ 16 | InputSettings {}, 17 | RenderSettings { 18 | camera: camera 19 | skyColor: "#00C5FF" 20 | skyIntensity: 0.5 21 | } 22 | ] 23 | 24 | Camera { 25 | id: camera 26 | position: Qt.vector3d(0, 0, 4) 27 | exposure: 1.0 28 | fieldOfView: 60 29 | } 30 | FirstPersonCameraController { 31 | camera: camera 32 | moveSpeed: 2 33 | lookSpeed: 180 34 | } 35 | 36 | // Sun 37 | Entity { 38 | Transform { 39 | id: sunTransform 40 | rotationX: 60 41 | rotationZ: 35 42 | } 43 | DistantLight { 44 | id: sunLight 45 | color: Qt3DRaytrace.lrgba(1.0, 0.9, 0.8) 46 | intensity: 4 47 | } 48 | components: [ sunTransform, sunLight ] 49 | } 50 | 51 | // Monkey 52 | Entity { 53 | Material { 54 | id: monkeyMaterial 55 | albedo: "crimson" 56 | roughness: 0.5 57 | } 58 | Mesh { 59 | id: monkeyMesh 60 | source: "monkey.obj" 61 | } 62 | components: [ monkeyMaterial, monkeyMesh ] 63 | } 64 | 65 | // Ground 66 | Entity { 67 | Transform { 68 | id: groundTransform 69 | translation: Qt.vector3d(0, -1, 0) 70 | scale: 10 71 | } 72 | Material { 73 | id: groundMaterial 74 | albedo: "white" 75 | } 76 | Mesh { 77 | id: groundMesh 78 | source: "plane.obj" 79 | } 80 | components: [ groundTransform, groundMaterial, groundMesh ] 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /examples/raytrace-qml/raytrace-qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | main.qml 5 | ../assets/plane.obj 6 | ../assets/monkey.obj 7 | 8 | 9 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qabstracttexture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QAbstractTexturePrivate; 18 | 19 | class QT3DRAYTRACESHARED_EXPORT QAbstractTexture : public Qt3DCore::QNode 20 | { 21 | Q_OBJECT 22 | Q_PROPERTY(Qt3DRaytrace::QTextureImage* image READ image WRITE setImage NOTIFY imageChanged) 23 | public: 24 | explicit QAbstractTexture(Qt3DCore::QNode *parent = nullptr); 25 | 26 | QTextureImage *image() const; 27 | 28 | QTextureImageFactoryPtr imageFactory() const; 29 | void setImageFactory(const QTextureImageFactoryPtr &factory); 30 | 31 | public slots: 32 | void setImage(QTextureImage *image); 33 | 34 | signals: 35 | void imageChanged(QTextureImage *image); 36 | 37 | protected: 38 | explicit QAbstractTexture(QAbstractTexturePrivate &dd, Qt3DCore::QNode *parent = nullptr); 39 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 40 | 41 | private: 42 | Q_DECLARE_PRIVATE(QAbstractTexture) 43 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 44 | }; 45 | 46 | } // Qt3DRaytrace 47 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qcameralens.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | class QCameraLensPrivate; 16 | 17 | class QT3DRAYTRACESHARED_EXPORT QCameraLens : public Qt3DCore::QComponent 18 | { 19 | Q_OBJECT 20 | Q_DECLARE_PRIVATE(QCameraLens) 21 | Q_PROPERTY(float aspectRatio READ aspectRatio WRITE setAspectRatio NOTIFY aspectRatioChanged) 22 | Q_PROPERTY(float fieldOfView READ fieldOfView WRITE setFieldOfView NOTIFY fieldOfViewChanged) 23 | Q_PROPERTY(float diameter READ diameter WRITE setDiameter NOTIFY diameterChanged) 24 | Q_PROPERTY(float focalDistance READ focalDistance WRITE setFocalDistance NOTIFY focalDistanceChanged) 25 | Q_PROPERTY(float gamma READ gamma WRITE setGamma NOTIFY gammaChanged) 26 | Q_PROPERTY(float exposure READ exposure WRITE setExposure NOTIFY exposureChanged) 27 | Q_PROPERTY(float tonemapFactor READ tonemapFactor WRITE setTonemapFactor NOTIFY tonemapFactorChanged) 28 | public: 29 | explicit QCameraLens(Qt3DCore::QNode *parent = nullptr); 30 | 31 | float aspectRatio() const; 32 | float fieldOfView() const; 33 | float diameter() const; 34 | float focalDistance() const; 35 | float gamma() const; 36 | float exposure() const; 37 | float tonemapFactor() const; 38 | 39 | public slots: 40 | void setAspectRatio(float aspectRatio); 41 | void setFieldOfView(float fov); 42 | void setDiameter(float diameter); 43 | void setFocalDistance(float distance); 44 | void setGamma(float gamma); 45 | void setExposure(float exposure); 46 | void setTonemapFactor(float factor); 47 | 48 | signals: 49 | void aspectRatioChanged(float aspectRatio); 50 | void fieldOfViewChanged(float fov); 51 | void diameterChanged(float diameter); 52 | void focalDistanceChanged(float distance); 53 | void gammaChanged(float gamma); 54 | void exposureChanged(float exposure); 55 | void tonemapFactorChanged(float factor); 56 | 57 | protected: 58 | explicit QCameraLens(QCameraLensPrivate &dd, QNode *parent = nullptr); 59 | 60 | private: 61 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 62 | }; 63 | 64 | } // Qt3DRaytrace 65 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qcolorspace.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | static inline QColor to_sRgb(const QColor &c) 17 | { 18 | auto sRgb = [](qreal u) -> qreal { 19 | if(u < 0.0031308) return u * 12.92; 20 | else return std::pow(u * 1.055, 1.0 / 2.4) - 0.055; 21 | }; 22 | return QColor::fromRgbF(sRgb(c.redF()), sRgb(c.greenF()), sRgb(c.blueF()), c.alphaF()); 23 | } 24 | 25 | static inline QColor to_linearRgb(const QColor &c) 26 | { 27 | auto inv_sRgb = [](qreal u) -> qreal { 28 | if(u < 0.04045) return u / 12.92; 29 | else return std::pow(((u + 0.055) / 1.055), 2.4); 30 | }; 31 | return QColor::fromRgbF(inv_sRgb(c.redF()), inv_sRgb(c.greenF()), inv_sRgb(c.blueF()), c.alphaF()); 32 | } 33 | 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qdistantlight.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QDistantLightPrivate; 18 | 19 | class QT3DRAYTRACESHARED_EXPORT QDistantLight : public Qt3DCore::QComponent 20 | { 21 | Q_OBJECT 22 | Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged) 23 | Q_PROPERTY(float intensity READ intensity WRITE setIntensity NOTIFY intensityChanged) 24 | Q_PROPERTY(QVector3D direction READ direction WRITE setDirection NOTIFY directionChanged) 25 | public: 26 | explicit QDistantLight(Qt3DCore::QNode *parent = nullptr); 27 | 28 | QColor color() const; 29 | float intensity() const; 30 | QVector3D direction() const; 31 | 32 | public slots: 33 | void setColor(const QColor &color); 34 | void setIntensity(float intensity); 35 | void setDirection(const QVector3D &direction); 36 | 37 | signals: 38 | void colorChanged(const QColor &color); 39 | void intensityChanged(float intensity); 40 | void directionChanged(const QVector3D &direction); 41 | 42 | protected: 43 | explicit QDistantLight(QDistantLightPrivate &dd, Qt3DCore::QNode *parent = nullptr); 44 | 45 | private: 46 | Q_DECLARE_PRIVATE(QDistantLight) 47 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 48 | }; 49 | 50 | } // Qt3DRaytrace 51 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qgeometry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QGeometryPrivate; 18 | 19 | class QT3DRAYTRACESHARED_EXPORT QGeometry : public Qt3DCore::QNode 20 | { 21 | Q_OBJECT 22 | public: 23 | explicit QGeometry(Qt3DCore::QNode *parent = nullptr); 24 | 25 | const QGeometryData &data() const; 26 | const QVector &vertices() const; 27 | const QVector &faces() const; 28 | 29 | void setData(const QGeometryData &geometryData); 30 | void clearData(); 31 | 32 | signals: 33 | void dataChanged(const QGeometryData &geometryData); 34 | 35 | protected: 36 | explicit QGeometry(QGeometryPrivate &dd, Qt3DCore::QNode *parent = nullptr); 37 | 38 | private: 39 | Q_DECLARE_PRIVATE(QGeometry) 40 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 41 | }; 42 | 43 | } // Qt3DRaytrace 44 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qgeometrydata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | namespace Qt3DRaytrace { 18 | 19 | struct QVertex 20 | { 21 | QVector3D position; 22 | QVector3D normal; 23 | QVector3D tangent; 24 | QVector2D texcoord; 25 | }; 26 | 27 | struct QTriangle 28 | { 29 | quint32 vertices[3]; 30 | }; 31 | 32 | struct QGeometryData 33 | { 34 | QVector vertices; 35 | QVector faces; 36 | }; 37 | 38 | } // Qt3DRaytrace 39 | 40 | Q_DECLARE_METATYPE(Qt3DRaytrace::QVertex) 41 | Q_DECLARE_METATYPE(Qt3DRaytrace::QTriangle) 42 | Q_DECLARE_METATYPE(Qt3DRaytrace::QGeometryData) 43 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qgeometryfactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | class QGeometry; 16 | 17 | class QT3DRAYTRACESHARED_EXPORT QGeometryFactory 18 | { 19 | public: 20 | virtual ~QGeometryFactory() = default; 21 | virtual QGeometry *create() = 0; 22 | }; 23 | 24 | using QGeometryFactoryPtr = QSharedPointer; 25 | 26 | } // Qt3DRaytrace 27 | 28 | Q_DECLARE_METATYPE(Qt3DRaytrace::QGeometryFactoryPtr) 29 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qgeometryrenderer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QGeometryRendererPrivate; 18 | 19 | class QT3DRAYTRACESHARED_EXPORT QGeometryRenderer : public Qt3DCore::QComponent 20 | { 21 | Q_OBJECT 22 | Q_PROPERTY(Qt3DRaytrace::QGeometry* geometry READ geometry WRITE setGeometry NOTIFY geometryChanged) 23 | public: 24 | explicit QGeometryRenderer(Qt3DCore::QNode *parent = nullptr); 25 | 26 | QGeometry *geometry() const; 27 | 28 | QGeometryFactoryPtr geometryFactory() const; 29 | void setGeometryFactory(const QGeometryFactoryPtr &factory); 30 | 31 | public slots: 32 | void setGeometry(QGeometry *geometry); 33 | 34 | signals: 35 | void geometryChanged(QGeometry *geometry); 36 | 37 | protected: 38 | explicit QGeometryRenderer(QGeometryRendererPrivate &dd, Qt3DCore::QNode *parent = nullptr); 39 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 40 | 41 | private: 42 | Q_DECLARE_PRIVATE(QGeometryRenderer) 43 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 44 | }; 45 | 46 | } // Qt3DRaytrace 47 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qimagedata.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | // TODO: Add support for layers and mipmaps. 18 | struct QImageData 19 | { 20 | enum class ValueType { 21 | Undefined = 0, 22 | UInt8 = 1, 23 | Float16 = 2, 24 | Float32 = 4, 25 | }; 26 | enum class Format { 27 | Undefined = 0, 28 | RGB, 29 | BGR, 30 | RGBA, 31 | BGRA, 32 | }; 33 | 34 | int width = 0; 35 | int height = 0; 36 | int channels = 0; 37 | ValueType type = ValueType::Undefined; 38 | Format format = Format::Undefined; 39 | QByteArray data; 40 | }; 41 | 42 | using QImageDataPtr = QSharedPointer; 43 | 44 | } // Qt3DRaytrace 45 | 46 | Q_DECLARE_METATYPE(Qt3DRaytrace::QImageData) 47 | Q_DECLARE_METATYPE(Qt3DRaytrace::QImageDataPtr) 48 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qmaterial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | class QAbstractTexture; 17 | class QMaterialPrivate; 18 | 19 | class QT3DRAYTRACESHARED_EXPORT QMaterial : public Qt3DCore::QComponent 20 | { 21 | Q_OBJECT 22 | Q_PROPERTY(QColor albedo READ albedo WRITE setAlbedo NOTIFY albedoChanged) 23 | Q_PROPERTY(float roughness READ roughness WRITE setRoughness NOTIFY roughnessChanged) 24 | Q_PROPERTY(float metalness READ metalness WRITE setMetalness NOTIFY metalnessChanged) 25 | Q_PROPERTY(QColor emission READ emission WRITE setEmission NOTIFY emissionChanged) 26 | Q_PROPERTY(float emissionIntensity READ emissionIntensity WRITE setEmissionIntensity NOTIFY emissionIntensityChanged) 27 | Q_PROPERTY(Qt3DRaytrace::QAbstractTexture* albedoTexture READ albedoTexture WRITE setAlbedoTexture NOTIFY albedoTextureChanged) 28 | Q_PROPERTY(Qt3DRaytrace::QAbstractTexture* roughnessTexture READ roughnessTexture WRITE setRoughnessTexture NOTIFY roughnessTextureChanged) 29 | Q_PROPERTY(Qt3DRaytrace::QAbstractTexture* metalnessTexture READ metalnessTexture WRITE setMetalnessTexture NOTIFY metalnessTextureChanged) 30 | public: 31 | explicit QMaterial(Qt3DCore::QNode *parent = nullptr); 32 | 33 | QColor albedo() const; 34 | float roughness() const; 35 | float metalness() const; 36 | QColor emission() const; 37 | float emissionIntensity() const; 38 | 39 | QAbstractTexture *albedoTexture() const; 40 | QAbstractTexture *roughnessTexture() const; 41 | QAbstractTexture *metalnessTexture() const; 42 | 43 | public slots: 44 | void setAlbedo(const QColor &albedo); 45 | void setRoughness(float rougness); 46 | void setMetalness(float metalness); 47 | void setEmission(const QColor &emission); 48 | void setEmissionIntensity(float intensity); 49 | 50 | void setAlbedoTexture(QAbstractTexture *texture); 51 | void setRoughnessTexture(QAbstractTexture *texture); 52 | void setMetalnessTexture(QAbstractTexture *texture); 53 | 54 | signals: 55 | void albedoChanged(const QColor &albedo); 56 | void roughnessChanged(float roughness); 57 | void metalnessChanged(float metalness); 58 | void emissionChanged(const QColor &emission); 59 | void emissionIntensityChanged(float intensity); 60 | 61 | void albedoTextureChanged(QAbstractTexture *texture); 62 | void roughnessTextureChanged(QAbstractTexture *texture); 63 | void metalnessTextureChanged(QAbstractTexture *texture); 64 | 65 | protected: 66 | explicit QMaterial(QMaterialPrivate &dd, Qt3DCore::QNode *parent = nullptr); 67 | 68 | private: 69 | Q_DECLARE_PRIVATE(QMaterial) 70 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 71 | }; 72 | 73 | } // Qt3DRaytrace 74 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qmesh.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | class QMeshPrivate; 17 | 18 | class QT3DRAYTRACESHARED_EXPORT QMesh : public QGeometryRenderer 19 | { 20 | Q_OBJECT 21 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) 22 | Q_PROPERTY(Status status READ status NOTIFY statusChanged) 23 | public: 24 | explicit QMesh(Qt3DCore::QNode *parent = nullptr); 25 | 26 | enum Status { 27 | None = 0, 28 | Loading, 29 | Ready, 30 | Error, 31 | }; 32 | Q_ENUM(Status) 33 | 34 | QUrl source() const; 35 | Status status() const; 36 | 37 | public slots: 38 | void setSource(const QUrl &source); 39 | 40 | signals: 41 | void sourceChanged(const QUrl &source); 42 | void statusChanged(Status status); 43 | 44 | protected: 45 | explicit QMesh(QMeshPrivate &dd, Qt3DCore::QNode *parent = nullptr); 46 | 47 | private: 48 | Q_DECLARE_PRIVATE(QMesh) 49 | }; 50 | 51 | } // Qt3DRaytrace 52 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qraytraceaspect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | class QSurface; 16 | 17 | namespace Qt3DRaytrace { 18 | 19 | class QRaytraceAspectPrivate; 20 | 21 | class QT3DRAYTRACESHARED_EXPORT QRaytraceAspect : public Qt3DCore::QAbstractAspect 22 | { 23 | Q_OBJECT 24 | public: 25 | explicit QRaytraceAspect(QObject *parent = nullptr); 26 | 27 | QSurface *surface() const; 28 | void setSurface(QObject *surfaceObject); 29 | 30 | bool queryRenderStatistics(QRenderStatistics &statistics) const; 31 | 32 | public slots: 33 | void suspendJobs(); 34 | void resumeJobs(); 35 | void requestImage(Qt3DRaytrace::QRenderImage type); 36 | 37 | signals: 38 | void imageReady(Qt3DRaytrace::QRenderImage type, Qt3DRaytrace::QImageDataPtr image); 39 | 40 | protected: 41 | QRaytraceAspect(QRaytraceAspectPrivate &dd, QObject *parent); 42 | Q_DECLARE_PRIVATE(QRaytraceAspect) 43 | 44 | private: 45 | Q_INVOKABLE void grabImage(Qt3DRaytrace::QRenderImage type); 46 | 47 | QVector jobsToExecute(qint64 time) override; 48 | 49 | void onRegistered() override; 50 | void onUnregistered() override; 51 | void onEngineStartup() override; 52 | void onEngineShutdown() override; 53 | }; 54 | 55 | } // Qt3DRaytrace 56 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qrenderimage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | enum class QRenderImage 15 | { 16 | HDR, 17 | FinalLDR, 18 | }; 19 | 20 | struct QRenderStatistics 21 | { 22 | double cpuFrameTime; 23 | double gpuFrameTime; 24 | double totalRenderTime; 25 | unsigned int numFramesRendered; 26 | }; 27 | 28 | } // Qt3DRaytrace 29 | 30 | Q_DECLARE_METATYPE(Qt3DRaytrace::QRenderImage) 31 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qt3draytrace_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #if !QT_CONFIG(vulkan) 13 | #error "Quartz requires Qt version with Vulkan support enabled at compile time." 14 | #endif 15 | 16 | #if defined(QUARTZ_SHARED) 17 | # if defined(QT3DRAYTRACE_LIBRARY) 18 | # define QT3DRAYTRACESHARED_EXPORT Q_DECL_EXPORT 19 | # else 20 | # define QT3DRAYTRACESHARED_EXPORT Q_DECL_IMPORT 21 | # endif 22 | #else 23 | # define QT3DRAYTRACESHARED_EXPORT 24 | #endif 25 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qt3draytracecontext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Quick { 16 | 17 | class QT3DRAYTRACESHARED_EXPORT Qt3DRaytraceContext : public QObject 18 | { 19 | Q_OBJECT 20 | public: 21 | explicit Qt3DRaytraceContext(QObject *parent = nullptr); 22 | 23 | Q_INVOKABLE QColor lrgba(qreal r, qreal g, qreal b, qreal a=1.0) const; 24 | Q_INVOKABLE QColor srgba(qreal r, qreal g, qreal b, qreal a=1.0) const; 25 | }; 26 | 27 | } // Quick 28 | } // Qt3DRaytrace 29 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qtexture.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | class QTexturePrivate; 17 | 18 | class QT3DRAYTRACESHARED_EXPORT QTexture : public QAbstractTexture 19 | { 20 | Q_OBJECT 21 | Q_PROPERTY(QUrl source READ source WRITE setSource NOTIFY sourceChanged) 22 | Q_PROPERTY(Status status READ status NOTIFY statusChanged) 23 | public: 24 | explicit QTexture(Qt3DCore::QNode *parent = nullptr); 25 | 26 | enum Status { 27 | None = 0, 28 | Loading, 29 | Ready, 30 | Error, 31 | }; 32 | Q_ENUM(Status) 33 | 34 | QUrl source() const; 35 | Status status() const; 36 | 37 | public slots: 38 | void setSource(const QUrl &source); 39 | 40 | signals: 41 | void sourceChanged(const QUrl &source); 42 | void statusChanged(Status status); 43 | 44 | protected: 45 | explicit QTexture(QTexturePrivate &dd, Qt3DCore::QNode *parent = nullptr); 46 | 47 | private: 48 | Q_DECLARE_PRIVATE(QTexture) 49 | }; 50 | 51 | } // Qt3DRaytrace 52 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qtextureimage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | class QTextureImagePrivate; 17 | 18 | class QT3DRAYTRACESHARED_EXPORT QTextureImage : public Qt3DCore::QNode 19 | { 20 | Q_OBJECT 21 | public: 22 | explicit QTextureImage(Qt3DCore::QNode *parent = nullptr); 23 | 24 | const QImageData &data() const; 25 | 26 | void setData(const QImageData &imageData); 27 | void clearData(); 28 | 29 | signals: 30 | void imageDataChanged(const QImageData &imageData); 31 | 32 | protected: 33 | explicit QTextureImage(QTextureImagePrivate &dd, Qt3DCore::QNode *parent = nullptr); 34 | 35 | private: 36 | Q_DECLARE_PRIVATE(QTextureImage) 37 | Qt3DCore::QNodeCreatedChangeBasePtr createNodeCreationChange() const override; 38 | }; 39 | 40 | } // Qt3DRaytrace 41 | -------------------------------------------------------------------------------- /include/Qt3DRaytrace/qtextureimagefactory.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | class QTextureImage; 16 | 17 | class QT3DRAYTRACESHARED_EXPORT QTextureImageFactory 18 | { 19 | public: 20 | virtual ~QTextureImageFactory() = default; 21 | virtual QTextureImage *create() = 0; 22 | }; 23 | 24 | using QTextureImageFactoryPtr = QSharedPointer; 25 | 26 | } // Qt3DRaytrace 27 | 28 | Q_DECLARE_METATYPE(Qt3DRaytrace::QTextureImageFactoryPtr) 29 | -------------------------------------------------------------------------------- /include/Qt3DRaytraceExtras/qfirstpersoncameracontroller.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | class QCamera; 14 | } // Qt3DRaytrace 15 | 16 | namespace Qt3DRaytraceExtras { 17 | 18 | class QFirstPersonCameraControllerPrivate; 19 | 20 | class QT3DRAYTRACEEXTRASSHARED_EXPORT QFirstPersonCameraController : public Qt3DCore::QEntity 21 | { 22 | Q_OBJECT 23 | Q_DECLARE_PRIVATE(QFirstPersonCameraController) 24 | Q_PROPERTY(Qt3DRaytrace::QCamera *camera READ camera WRITE setCamera NOTIFY cameraChanged) 25 | Q_PROPERTY(float moveSpeed READ moveSpeed WRITE setMoveSpeed NOTIFY moveSpeedChanged) 26 | Q_PROPERTY(float lookSpeed READ lookSpeed WRITE setLookSpeed NOTIFY lookSpeedChanged) 27 | Q_PROPERTY(float acceleration READ acceleration WRITE setAcceleration NOTIFY accelerationChanged) 28 | Q_PROPERTY(float deceleration READ deceleration WRITE setDeceleration NOTIFY decelerationChanged) 29 | public: 30 | explicit QFirstPersonCameraController(Qt3DCore::QNode *parent = nullptr); 31 | 32 | Qt3DRaytrace::QCamera *camera() const; 33 | float moveSpeed() const; 34 | float lookSpeed() const; 35 | float acceleration() const; 36 | float deceleration() const; 37 | 38 | public slots: 39 | void setCamera(Qt3DRaytrace::QCamera *camera); 40 | void setMoveSpeed(float moveSpeed); 41 | void setLookSpeed(float lookSpeed); 42 | void setAcceleration(float acceleration); 43 | void setDeceleration(float deceleration); 44 | 45 | signals: 46 | void cameraChanged(Qt3DRaytrace::QCamera *camera); 47 | void moveSpeedChanged(float moveSpeed); 48 | void lookSpeedChanged(float lookSpeed); 49 | void accelerationChanged(float acceleration); 50 | void decelerationChanged(float deceleration); 51 | 52 | protected: 53 | explicit QFirstPersonCameraController(QFirstPersonCameraControllerPrivate &dd, Qt3DCore::QNode *parent = nullptr); 54 | 55 | private slots: 56 | void frameAction(float dt); 57 | }; 58 | 59 | } // Qt3DRaytraceExtras 60 | -------------------------------------------------------------------------------- /include/Qt3DRaytraceExtras/qt3dquickwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | class QVulkanInstance; 16 | class QQmlEngine; 17 | 18 | namespace Qt3DCore { 19 | class QEntity; 20 | class QAbstractAspect; 21 | namespace Quick { 22 | class QQmlAspectEngine; 23 | } // Quick 24 | } // Qt3DCore 25 | 26 | namespace Qt3DInput { 27 | class QInputAspect; 28 | } // Qt3DInput 29 | 30 | namespace Qt3DRaytrace { 31 | class QRaytraceAspect; 32 | } // Qt3DRaytrace 33 | 34 | namespace Qt3DRaytraceExtras { 35 | namespace Quick { 36 | 37 | class Qt3DQuickWindowPrivate; 38 | 39 | class QT3DRAYTRACEEXTRASSHARED_EXPORT Qt3DQuickWindow : public QWindow 40 | { 41 | Q_OBJECT 42 | Q_DECLARE_PRIVATE(Qt3DQuickWindow) 43 | Q_PROPERTY(CameraAspectRatioMode cameraAspectRatioMode READ cameraAspectRatioMode WRITE setCameraAspectRatioMode NOTIFY cameraAspectRatioModeChanged) 44 | public: 45 | explicit Qt3DQuickWindow(QWindow *parent = nullptr); 46 | 47 | void registerAspect(Qt3DCore::QAbstractAspect *aspect); 48 | void registerAspect(const QString &name); 49 | 50 | Qt3DRaytrace::QRaytraceAspect *raytraceAspect() const; 51 | Qt3DInput::QInputAspect *inputAspect() const; 52 | 53 | QQmlEngine *qmlEngine() const; 54 | 55 | void setSource(const QUrl &source); 56 | Qt3DCore::Quick::QQmlAspectEngine *engine() const; 57 | 58 | enum CameraAspectRatioMode { 59 | AutomaticAspectRatio, 60 | UserAspectRatio, 61 | }; 62 | Q_ENUM(CameraAspectRatioMode) 63 | 64 | CameraAspectRatioMode cameraAspectRatioMode() const; 65 | void setCameraAspectRatioMode(CameraAspectRatioMode mode); 66 | 67 | signals: 68 | void cameraAspectRatioModeChanged(CameraAspectRatioMode mode); 69 | void aboutToClose(); 70 | 71 | protected: 72 | Qt3DQuickWindow(Qt3DQuickWindowPrivate &dd, QWindow *parent); 73 | 74 | virtual bool event(QEvent *event) override; 75 | virtual void showEvent(QShowEvent *event) override; 76 | 77 | private slots: 78 | void sceneCreated(QObject *root); 79 | void updateCameraAspectRatio(); 80 | }; 81 | 82 | } // Quick 83 | } // Qt3DRaytraceExtras 84 | -------------------------------------------------------------------------------- /include/Qt3DRaytraceExtras/qt3draytraceextras_global.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #if !QT_CONFIG(vulkan) 13 | #error "Quartz requires Qt version with Vulkan support enabled at compile time." 14 | #endif 15 | 16 | #if defined(QUARTZ_SHARED) 17 | # if defined(QT3DRAYTRACEEXTRAS_LIBRARY) 18 | # define QT3DRAYTRACEEXTRASSHARED_EXPORT Q_DECL_EXPORT 19 | # else 20 | # define QT3DRAYTRACEEXTRASSHARED_EXPORT Q_DECL_IMPORT 21 | # endif 22 | #else 23 | # define QT3DRAYTRACEEXTRASSHARED_EXPORT 24 | #endif 25 | -------------------------------------------------------------------------------- /include/Qt3DRaytraceExtras/qt3dwindow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | class QVulkanInstance; 15 | 16 | namespace Qt3DCore { 17 | class QEntity; 18 | class QAbstractAspect; 19 | } // Qt3DCore 20 | 21 | namespace Qt3DInput { 22 | class QInputAspect; 23 | } // Qt3DInput 24 | 25 | namespace Qt3DRaytrace { 26 | class QRaytraceAspect; 27 | } // Qt3DRaytrace 28 | 29 | namespace Qt3DRaytraceExtras { 30 | 31 | class Qt3DWindowPrivate; 32 | 33 | class QT3DRAYTRACEEXTRASSHARED_EXPORT Qt3DWindow : public QWindow 34 | { 35 | Q_OBJECT 36 | Q_DECLARE_PRIVATE(Qt3DWindow) 37 | public: 38 | explicit Qt3DWindow(QWindow *parent = nullptr); 39 | 40 | void registerAspect(Qt3DCore::QAbstractAspect *aspect); 41 | void registerAspect(const QString &name); 42 | 43 | Qt3DRaytrace::QRaytraceAspect *raytraceAspect() const; 44 | Qt3DInput::QInputAspect *inputAspect() const; 45 | 46 | void setRootEntity(Qt3DCore::QEntity *root); 47 | 48 | signals: 49 | void aboutToClose(); 50 | 51 | protected: 52 | Qt3DWindow(Qt3DWindowPrivate &dd, QWindow *parent); 53 | 54 | virtual bool event(QEvent *event) override; 55 | virtual void showEvent(QShowEvent *event) override; 56 | }; 57 | 58 | } // Qt3DRaytraceExtras 59 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(QUARTZ_PUBLIC_API ${CMAKE_SOURCE_DIR}/include) 2 | 3 | add_subdirectory(raytrace) 4 | add_subdirectory(extras) 5 | add_subdirectory(qml) 6 | -------------------------------------------------------------------------------- /src/extras/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODULE_NAME "Qt3DRaytraceExtras") 2 | set(MODULE_LIBNAME "Qt53DRaytraceExtras") 3 | set(MODULE_API ${QUARTZ_PUBLIC_API}/${MODULE_NAME}) 4 | set(MODULE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 5 | 6 | set(MODULE_PATH ${MODULE_PATH} ${MODULE_BINARY_DIR} PARENT_SCOPE) 7 | 8 | find_package(Qt5 COMPONENTS Core Gui 3DCore 3DQuick 3DInput 3DLogic REQUIRED) 9 | 10 | set(SOURCES_PRIVATE 11 | qt3draytraceextras_global_p.h 12 | qt3dwindow.cpp 13 | qt3dwindow_p.h 14 | qt3dquickwindow.cpp 15 | qt3dquickwindow_p.h 16 | qfirstpersoncameracontroller.cpp 17 | qfirstpersoncameracontroller_p.h 18 | ) 19 | 20 | set(SOURCES_PUBLIC 21 | ${MODULE_API}/qt3draytraceextras_global.h 22 | ${MODULE_API}/qt3dwindow.h 23 | ${MODULE_API}/qt3dquickwindow.h 24 | ${MODULE_API}/qfirstpersoncameracontroller.h 25 | ) 26 | 27 | add_library(${MODULE_NAME} ${SOURCES_PRIVATE} ${SOURCES_PUBLIC}) 28 | set_target_properties(${MODULE_NAME} PROPERTIES OUTPUT_NAME ${MODULE_LIBNAME}) 29 | 30 | target_include_directories(${MODULE_NAME} PUBLIC ${QUARTZ_PUBLIC_API}) 31 | target_compile_features(${MODULE_NAME} PUBLIC cxx_std_14) 32 | target_compile_definitions(${MODULE_NAME} PRIVATE VK_NO_PROTOTYPES) 33 | target_link_libraries(${MODULE_NAME} Qt5::Core Qt5::Gui Qt5::3DCore Qt5::3DQuick Qt5::3DInput Qt5::3DLogic Qt3DRaytrace) 34 | 35 | if(BUILD_SHARED_LIBS) 36 | target_compile_definitions(${MODULE_NAME} 37 | PUBLIC QUARTZ_SHARED 38 | PRIVATE QT3DRAYTRACEEXTRAS_LIBRARY 39 | ) 40 | endif() 41 | -------------------------------------------------------------------------------- /src/extras/qfirstpersoncameracontroller_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace Qt3DLogic { 17 | class QFrameAction; 18 | } // Qt3DLogic 19 | 20 | namespace Qt3DInput { 21 | class QKeyboardDevice; 22 | class QMouseDevice; 23 | class QLogicalDevice; 24 | class QAxis; 25 | class QAnalogAxisInput; 26 | class QButtonAxisInput; 27 | } // Qt3DInput 28 | 29 | namespace Qt3DRaytraceExtras { 30 | 31 | class QFirstPersonCameraControllerPrivate : public Qt3DCore::QEntityPrivate 32 | { 33 | Q_DECLARE_PUBLIC(QFirstPersonCameraController) 34 | public: 35 | QFirstPersonCameraControllerPrivate(); 36 | 37 | void applyInputAcceleration(); 38 | 39 | Qt3DRaytrace::QCamera *m_camera; 40 | 41 | Qt3DInput::QKeyboardDevice *m_keyboardDevice; 42 | Qt3DInput::QMouseDevice *m_mouseDevice; 43 | 44 | Qt3DInput::QLogicalDevice *m_logicalDevice; 45 | Qt3DLogic::QFrameAction *m_frameAction; 46 | 47 | Qt3DInput::QAxis *m_rxAxis; 48 | Qt3DInput::QAxis *m_ryAxis; 49 | Qt3DInput::QAxis *m_txAxis; 50 | Qt3DInput::QAxis *m_tyAxis; 51 | Qt3DInput::QAxis *m_tzAxis; 52 | 53 | Qt3DInput::QAnalogAxisInput *m_mouseRxInput; 54 | Qt3DInput::QAnalogAxisInput *m_mouseRyInput; 55 | 56 | Qt3DInput::QButtonAxisInput *m_keyboardTxPosInput; 57 | Qt3DInput::QButtonAxisInput *m_keyboardTyPosInput; 58 | Qt3DInput::QButtonAxisInput *m_keyboardTzPosInput; 59 | Qt3DInput::QButtonAxisInput *m_keyboardTxNegInput; 60 | Qt3DInput::QButtonAxisInput *m_keyboardTyNegInput; 61 | Qt3DInput::QButtonAxisInput *m_keyboardTzNegInput; 62 | 63 | float m_moveSpeed; 64 | float m_lookSpeed; 65 | float m_acceleration; 66 | float m_deceleration; 67 | }; 68 | 69 | } // Qt3DRaytraceExtras 70 | -------------------------------------------------------------------------------- /src/extras/qt3dquickwindow_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace Qt3DRaytraceExtras { 24 | namespace Quick { 25 | 26 | class Qt3DQuickWindowPrivate : public QWindowPrivate 27 | { 28 | Q_DECLARE_PUBLIC(Qt3DQuickWindow) 29 | public: 30 | Qt3DQuickWindowPrivate(); 31 | 32 | QScopedPointer m_engine; 33 | 34 | Qt3DRaytrace::QRaytraceAspect *m_raytraceAspect; 35 | Qt3DInput::QInputAspect *m_inputAspect; 36 | Qt3DLogic::QLogicAspect *m_logicAspect; 37 | 38 | QPointer m_camera; 39 | Qt3DQuickWindow::CameraAspectRatioMode m_cameraAspectRatioMode; 40 | 41 | QUrl m_source; 42 | bool m_initialized; 43 | }; 44 | 45 | } // Quick 46 | } // Qt3DRaytraceExtras 47 | -------------------------------------------------------------------------------- /src/extras/qt3draytraceextras_global_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | -------------------------------------------------------------------------------- /src/extras/qt3dwindow_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | 19 | #include 20 | 21 | namespace Qt3DRaytraceExtras { 22 | 23 | class Qt3DWindowPrivate : public QWindowPrivate 24 | { 25 | Q_DECLARE_PUBLIC(Qt3DWindow) 26 | public: 27 | Qt3DWindowPrivate(); 28 | ~Qt3DWindowPrivate(); 29 | 30 | QScopedPointer m_aspectEngine; 31 | 32 | Qt3DRaytrace::QRaytraceAspect *m_raytraceAspect; 33 | Qt3DInput::QInputAspect *m_inputAspect; 34 | Qt3DLogic::QLogicAspect *m_logicAspect; 35 | 36 | Qt3DInput::QInputSettings *m_inputSettings; 37 | Qt3DCore::QEntity *m_root; 38 | Qt3DCore::QEntity *m_userRoot; 39 | 40 | bool m_initialized = false; 41 | }; 42 | 43 | } // Qt3DRaytraceExtras 44 | -------------------------------------------------------------------------------- /src/qml/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | function(qml_typeinfo QML_PATH QML_VERSION OUTPUT_PATH) 2 | find_program(QMLPLUGINDUMP NAMES qmlplugindump qmlplugindump.exe HINTS ${QTDIR}/bin) 3 | if(WIN32) 4 | add_custom_command( 5 | TARGET ${MODULE_NAME} 6 | POST_BUILD 7 | COMMAND 8 | ${CMAKE_COMMAND} -E env "PATH=${QTDIR}/bin;${THIRDPARTY_PATH};${MODULE_PATH};$ENV{PATH}" 9 | ${QMLPLUGINDUMP} -nonrelocatable ${QML_PATH} ${QML_VERSION} "${PROJECT_BINARY_DIR}/qml" > "${PROJECT_BINARY_DIR}/qml/${OUTPUT_PATH}") 10 | else() 11 | add_custom_command( 12 | TARGET ${MODULE_NAME} 13 | POST_BUILD 14 | COMMAND 15 | ${QMLPLUGINDUMP} -nonrelocatable ${QML_PATH} ${QML_VERSION} "${PROJECT_BINARY_DIR}/qml" > "${PROJECT_BINARY_DIR}/qml/${OUTPUT_PATH}") 16 | endif() 17 | endfunction() 18 | 19 | if(BUILD_SHARED_LIBS) 20 | add_subdirectory(quick3draytrace) 21 | add_subdirectory(quick3draytraceextras) 22 | endif() 23 | -------------------------------------------------------------------------------- /src/qml/quick3draytrace/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODULE_NAME "quick3draytraceplugin") 2 | set(MODULE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 3 | 4 | find_package(Qt5 COMPONENTS Core Qml REQUIRED) 5 | 6 | add_library(${MODULE_NAME} 7 | qtquick3draytraceplugin.cpp 8 | qtquick3draytraceplugin.h 9 | qmldir 10 | ) 11 | 12 | target_include_directories(${MODULE_NAME} 13 | PUBLIC ${QUARTZ_PUBLIC_API} 14 | ) 15 | 16 | target_compile_features(${MODULE_NAME} PUBLIC cxx_std_14) 17 | target_link_libraries(${MODULE_NAME} Qt5::Core Qt5::Qml Qt3DRaytrace) 18 | 19 | target_compile_definitions(${MODULE_NAME} 20 | PUBLIC QUARTZ_SHARED 21 | PRIVATE QT3DQUICK3DRAYTRACEPLUGIN_LIBRARY 22 | ) 23 | 24 | add_custom_command( 25 | TARGET ${MODULE_NAME} 26 | POST_BUILD 27 | COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/qml/Qt3D/Raytrace" 28 | COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" "${PROJECT_BINARY_DIR}/qml/Qt3D/Raytrace" 29 | COMMAND ${CMAKE_COMMAND} -E copy "$" "${PROJECT_BINARY_DIR}/qml/Qt3D/Raytrace" 30 | ) 31 | 32 | if(DUMP_QML_TYPEINFO) 33 | qml_typeinfo("Qt3D.Raytrace" "1.0" "Qt3D/Raytrace/plugins.qmltypes") 34 | endif() 35 | -------------------------------------------------------------------------------- /src/qml/quick3draytrace/qmldir: -------------------------------------------------------------------------------- 1 | module Qt3D.Raytrace 2 | plugin quick3draytraceplugin 3 | classname Qt3DQuick3DRaytracePlugin 4 | -------------------------------------------------------------------------------- /src/qml/quick3draytrace/qtquick3draytraceplugin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | void Qt3DQuick3DRaytracePlugin::registerTypes(const char *uri) 24 | { 25 | // Context 26 | qmlRegisterSingletonType(uri, 1, 0, "Qt3DRaytrace", [](QQmlEngine*, QJSEngine*) -> QObject* { 27 | return new Qt3DRaytrace::Quick::Qt3DRaytraceContext; 28 | }); 29 | 30 | // Geometry 31 | qmlRegisterType(uri, 1, 0, "Geometry"); 32 | qmlRegisterType(uri, 1, 0, "GeometryRenderer"); 33 | qmlRegisterType(uri, 1, 0, "Mesh"); 34 | 35 | // Textures 36 | qmlRegisterType(uri, 1, 0, "TextureImage"); 37 | qmlRegisterType(uri, 1, 0, "AbstractTexture"); 38 | qmlRegisterType(uri, 1, 0, "Texture"); 39 | 40 | // Material 41 | qmlRegisterType(uri, 1, 0, "Material"); 42 | 43 | // Lights 44 | qmlRegisterType(uri, 1, 0, "DistantLight"); 45 | 46 | // Camera 47 | qmlRegisterType(uri, 1, 0, "Camera"); 48 | qmlRegisterType(uri, 1, 0, "CameraLens"); 49 | 50 | // Settings 51 | qmlRegisterType(uri, 1, 0, "RenderSettings"); 52 | 53 | // Module 54 | qmlRegisterModule(uri, 1, 0); 55 | } 56 | -------------------------------------------------------------------------------- /src/qml/quick3draytrace/qtquick3draytraceplugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | class Qt3DQuick3DRaytracePlugin final : public QQmlExtensionPlugin 12 | { 13 | Q_OBJECT 14 | Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) 15 | public: 16 | void registerTypes(const char *uri) override; 17 | }; 18 | -------------------------------------------------------------------------------- /src/qml/quick3draytraceextras/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(MODULE_NAME "quick3draytraceextrasplugin") 2 | set(MODULE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) 3 | 4 | find_package(Qt5 COMPONENTS Core Qml REQUIRED) 5 | 6 | add_library(${MODULE_NAME} 7 | qtquick3draytraceextrasplugin.cpp 8 | qtquick3draytraceextrasplugin.h 9 | qmldir 10 | ) 11 | 12 | target_include_directories(${MODULE_NAME} 13 | PUBLIC ${QUARTZ_PUBLIC_API} 14 | ) 15 | 16 | target_compile_features(${MODULE_NAME} PUBLIC cxx_std_14) 17 | target_link_libraries(${MODULE_NAME} Qt5::Core Qt5::Qml Qt3DRaytraceExtras) 18 | 19 | target_compile_definitions(${MODULE_NAME} 20 | PUBLIC QUARTZ_SHARED 21 | PRIVATE QT3DQUICK3DRAYTRACEEXTRASPLUGIN_LIBRARY 22 | ) 23 | 24 | add_custom_command( 25 | TARGET ${MODULE_NAME} 26 | POST_BUILD 27 | COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/qml/Qt3D/RaytraceExtras" 28 | COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/qmldir" "${PROJECT_BINARY_DIR}/qml/Qt3D/RaytraceExtras" 29 | COMMAND ${CMAKE_COMMAND} -E copy "$" "${PROJECT_BINARY_DIR}/qml/Qt3D/RaytraceExtras" 30 | ) 31 | 32 | if(DUMP_QML_TYPEINFO) 33 | qml_typeinfo("Qt3D.RaytraceExtras" "1.0" "Qt3D/RaytraceExtras/plugins.qmltypes") 34 | endif() 35 | -------------------------------------------------------------------------------- /src/qml/quick3draytraceextras/qmldir: -------------------------------------------------------------------------------- 1 | module Qt3D.RaytraceExtras 2 | plugin quick3draytraceextrasplugin 3 | classname Qt3DQuick3DRaytraceExtrasPlugin 4 | -------------------------------------------------------------------------------- /src/qml/quick3draytraceextras/qtquick3draytraceextrasplugin.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | void Qt3DQuick3DRaytraceExtrasPlugin::registerTypes(const char *uri) 13 | { 14 | // Camera controllers 15 | qmlRegisterType(uri, 1, 0, "FirstPersonCameraController"); 16 | 17 | // Module 18 | qmlRegisterModule(uri, 1, 0); 19 | } 20 | -------------------------------------------------------------------------------- /src/qml/quick3draytraceextras/qtquick3draytraceextrasplugin.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | class Qt3DQuick3DRaytraceExtrasPlugin final : public QQmlExtensionPlugin 12 | { 13 | Q_OBJECT 14 | Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) 15 | public: 16 | void registerTypes(const char *uri) override; 17 | }; 18 | -------------------------------------------------------------------------------- /src/raytrace/backend/abstractrenderer_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | class QObject; 17 | class QSurface; 18 | 19 | namespace Qt3DCore { 20 | class QAbstractFrameAdvanceService; 21 | } // Qt3DCore 22 | 23 | namespace Qt3DRaytrace { 24 | namespace Raytrace { 25 | 26 | class BackendNode; 27 | class Entity; 28 | class RenderSettings; 29 | 30 | struct NodeManagers; 31 | 32 | class AbstractRenderer 33 | { 34 | public: 35 | enum DirtyFlag { 36 | EntityDirty = 1 << 0, 37 | TransformDirty = 1 << 1, 38 | GeometryDirty = 1 << 2, 39 | TextureDirty = 1 << 3, 40 | MaterialDirty = 1 << 4, 41 | LightDirty = 1 << 5, 42 | CameraDirty = 1 << 6, 43 | NoneDirty = 0, 44 | AllDirty = 0xffffff, 45 | }; 46 | Q_DECLARE_FLAGS(DirtySet, DirtyFlag) 47 | 48 | virtual ~AbstractRenderer() = default; 49 | 50 | virtual bool initialize() = 0; 51 | virtual void shutdown() = 0; 52 | 53 | virtual void markDirty(DirtySet changes, BackendNode *node) = 0; 54 | 55 | virtual QSurface *surface() const = 0; 56 | virtual Entity *sceneRoot() const = 0; 57 | virtual RenderSettings *settings() const = 0; 58 | virtual QRenderStatistics statistics() const = 0; 59 | 60 | virtual void setSurface(QObject *surfaceObject) = 0; 61 | virtual void setSceneRoot(Entity *rootEntity) = 0; 62 | virtual void setSettings(RenderSettings *settings) = 0; 63 | virtual void setNodeManagers(NodeManagers *nodeManagers) = 0; 64 | 65 | virtual QImageData grabImage(QRenderImage type) = 0; 66 | 67 | virtual Qt3DCore::QAbstractFrameAdvanceService *frameAdvanceService() const = 0; 68 | 69 | virtual QVector jobsToExecute(qint64 time) = 0; 70 | }; 71 | 72 | } // Raytrace 73 | } // Qt3DRaytrace 74 | -------------------------------------------------------------------------------- /src/raytrace/backend/abstracttexture.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | using namespace Qt3DCore; 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Raytrace { 18 | 19 | AbstractTexture::AbstractTexture() 20 | : BackendNode(ReadWrite) 21 | , m_manager(nullptr) 22 | {} 23 | 24 | void AbstractTexture::setManager(TextureManager *manager) 25 | { 26 | Q_ASSERT(manager); 27 | m_manager = manager; 28 | } 29 | 30 | void AbstractTexture::sceneChangeEvent(const QSceneChangePtr &change) 31 | { 32 | if(change->type() == PropertyUpdated) { 33 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 34 | const auto propertyName = propertyChange->propertyName(); 35 | if(propertyName == QByteArrayLiteral("image")) { 36 | m_imageId = propertyChange->value().value(); 37 | } 38 | else if(propertyName == QByteArrayLiteral("imageFactory")) { 39 | m_imageFactory = propertyChange->value().value(); 40 | if(m_imageFactory && m_manager) { 41 | m_manager->markComponentDirty(peerId()); 42 | } 43 | } 44 | } 45 | 46 | markDirty(AbstractRenderer::TextureDirty); 47 | BackendNode::sceneChangeEvent(change); 48 | } 49 | 50 | void AbstractTexture::loadImage() 51 | { 52 | Q_ASSERT(m_imageFactory); 53 | 54 | std::unique_ptr image(m_imageFactory->create()); 55 | if(image) { 56 | image->moveToThread(QCoreApplication::instance()->thread()); 57 | 58 | auto change = QTextureImageChangePtr::create(peerId()); 59 | change->setDeliveryFlags(QSceneChange::Nodes); 60 | change->setPropertyName("image"); 61 | change->data = std::move(image); 62 | notifyObservers(change); 63 | } 64 | } 65 | 66 | void AbstractTexture::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 67 | { 68 | const auto typedChange = qSharedPointerCast>(change); 69 | const auto &data = typedChange->data; 70 | 71 | m_imageId = data.imageId; 72 | m_imageFactory = data.imageFactory; 73 | if(m_imageFactory && m_manager) { 74 | m_manager->markComponentDirty(peerId()); 75 | } 76 | 77 | markDirty(AbstractRenderer::TextureDirty); 78 | } 79 | 80 | } // Raytrace 81 | } // Qt3DRaytrace 82 | -------------------------------------------------------------------------------- /src/raytrace/backend/abstracttexture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Raytrace { 15 | 16 | class TextureManager; 17 | 18 | class AbstractTexture : public BackendNode 19 | { 20 | public: 21 | AbstractTexture(); 22 | 23 | void setManager(TextureManager *manager); 24 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 25 | void loadImage(); 26 | 27 | Qt3DCore::QNodeId imageId() const { return m_imageId; } 28 | QTextureImageFactoryPtr imageFactory() const { return m_imageFactory; } 29 | 30 | private: 31 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 32 | 33 | TextureManager *m_manager; 34 | Qt3DCore::QNodeId m_imageId; 35 | QTextureImageFactoryPtr m_imageFactory; 36 | }; 37 | 38 | class TextureNodeMapper final : public BackendNodeMapper 39 | { 40 | public: 41 | TextureNodeMapper(TextureManager *manager, AbstractRenderer *renderer) 42 | : BackendNodeMapper(manager, renderer) 43 | {} 44 | 45 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 46 | { 47 | auto texture = static_cast(BackendNodeMapper::create(change)); 48 | texture->setManager(m_manager); 49 | return texture; 50 | } 51 | }; 52 | 53 | } // Raytrace 54 | } // Qt3DRaytrace 55 | -------------------------------------------------------------------------------- /src/raytrace/backend/backendnode.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | 9 | using namespace Qt3DCore; 10 | 11 | namespace Qt3DRaytrace { 12 | namespace Raytrace { 13 | 14 | BackendNode::BackendNode(QBackendNode::Mode mode) 15 | : QBackendNode(mode) 16 | {} 17 | 18 | void BackendNode::markDirty(AbstractRenderer::DirtySet changes) 19 | { 20 | Q_ASSERT(m_renderer); 21 | m_renderer->markDirty(changes, this); 22 | } 23 | 24 | } // Raytrace 25 | } // Qt3DRaytrace 26 | -------------------------------------------------------------------------------- /src/raytrace/backend/backendnode_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | class BackendNode : public Qt3DCore::QBackendNode 18 | { 19 | public: 20 | explicit BackendNode(Qt3DCore::QBackendNode::Mode mode = ReadOnly); 21 | 22 | void setRenderer(AbstractRenderer *renderer) 23 | { 24 | m_renderer = renderer; 25 | } 26 | 27 | protected: 28 | void markDirty(AbstractRenderer::DirtySet changes); 29 | 30 | AbstractRenderer *m_renderer = nullptr; 31 | }; 32 | 33 | template 34 | class BackendNodeMapper : public Qt3DCore::QBackendNodeMapper 35 | { 36 | public: 37 | BackendNodeMapper(ManagerType *manager, AbstractRenderer *renderer) 38 | : m_manager(manager) 39 | , m_renderer(renderer) 40 | {} 41 | 42 | virtual Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 43 | { 44 | BackendNodeType *backendNode = m_manager->getOrCreateResource(change->subjectId()); 45 | backendNode->setRenderer(m_renderer); 46 | return backendNode; 47 | } 48 | 49 | Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const override 50 | { 51 | return m_manager->lookupResource(id); 52 | } 53 | 54 | void destroy(Qt3DCore::QNodeId id) const override 55 | { 56 | m_manager->releaseResource(id); 57 | } 58 | 59 | protected: 60 | ManagerType *m_manager; 61 | AbstractRenderer *m_renderer; 62 | }; 63 | 64 | } // Raytrace 65 | } // Qt3DRaytrace 66 | -------------------------------------------------------------------------------- /src/raytrace/backend/cameralens.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | using namespace Qt3DCore; 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | CameraLens::CameraLens() 18 | : BackendNode(BackendNode::ReadOnly) 19 | {} 20 | 21 | void CameraLens::sceneChangeEvent(const QSceneChangePtr &change) 22 | { 23 | if(change->type() == PropertyUpdated) { 24 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 25 | if(propertyChange->propertyName() == QByteArrayLiteral("fieldOfView")) { 26 | m_fieldOfView = propertyChange->value().value(); 27 | } 28 | else if(propertyChange->propertyName() == QByteArrayLiteral("aspectRatio")) { 29 | m_aspectRatio = propertyChange->value().value(); 30 | } 31 | else if(propertyChange->propertyName() == QByteArrayLiteral("diameter")) { 32 | m_diameter = propertyChange->value().value(); 33 | } 34 | else if(propertyChange->propertyName() == QByteArrayLiteral("focalDistance")) { 35 | m_focalDistance = propertyChange->value().value(); 36 | } 37 | else if(propertyChange->propertyName() == QByteArrayLiteral("gamma")) { 38 | m_gamma = propertyChange->value().value(); 39 | } 40 | else if(propertyChange->propertyName() == QByteArrayLiteral("exposure")) { 41 | m_exposure = propertyChange->value().value(); 42 | } 43 | else if(propertyChange->propertyName() == QByteArrayLiteral("tonemapFactor")) { 44 | m_tonemapFactor = propertyChange->value().value(); 45 | } 46 | markDirty(AbstractRenderer::CameraDirty); 47 | } 48 | BackendNode::sceneChangeEvent(change); 49 | } 50 | 51 | void CameraLens::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 52 | { 53 | const auto typedChange = qSharedPointerCast>(change); 54 | const auto &data = typedChange->data; 55 | 56 | m_aspectRatio = data.aspectRatio; 57 | m_fieldOfView = data.fieldOfView; 58 | m_diameter = data.diameter; 59 | m_focalDistance = data.focalDistance; 60 | m_gamma = data.gamma; 61 | m_exposure = data.exposure; 62 | m_tonemapFactor = data.tonemapFactor; 63 | 64 | markDirty(AbstractRenderer::CameraDirty); 65 | } 66 | 67 | } // Raytrace 68 | } // Qt3DRaytrace 69 | -------------------------------------------------------------------------------- /src/raytrace/backend/cameralens_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | class CameraLens : public BackendNode 16 | { 17 | public: 18 | CameraLens(); 19 | 20 | float fieldOfView() const { return m_fieldOfView; } 21 | float aspectRatio() const { return m_aspectRatio; } 22 | float diameter() const { return m_diameter; } 23 | float focalDistance() const { return m_focalDistance; } 24 | float gamma() const { return m_gamma; } 25 | float exposure() const { return m_exposure; } 26 | float tonemapFactor() const { return m_tonemapFactor; } 27 | 28 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 29 | 30 | private: 31 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 32 | 33 | float m_fieldOfView; 34 | float m_aspectRatio; 35 | float m_diameter; 36 | float m_focalDistance; 37 | float m_gamma; 38 | float m_exposure; 39 | float m_tonemapFactor; 40 | }; 41 | 42 | } // Raytrace 43 | } // Qt3DRaytrace 44 | -------------------------------------------------------------------------------- /src/raytrace/backend/distantlight.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace Qt3DCore; 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Raytrace { 17 | 18 | DistantLight::DistantLight() 19 | : BackendNode(ReadOnly) 20 | {} 21 | 22 | void DistantLight::sceneChangeEvent(const QSceneChangePtr &change) 23 | { 24 | if(change->type() == PropertyUpdated) { 25 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 26 | const auto propertyName = propertyChange->propertyName(); 27 | if(propertyName == QByteArrayLiteral("color")) { 28 | m_color = propertyChange->value().value(); 29 | } 30 | else if(propertyName == QByteArrayLiteral("intensity")) { 31 | m_intensity = qMax(propertyChange->value().value(), 0.0f); 32 | } 33 | else if(propertyName == QByteArrayLiteral("direction")) { 34 | m_direction = propertyChange->value().value(); 35 | } 36 | } 37 | 38 | markDirty(AbstractRenderer::LightDirty); 39 | BackendNode::sceneChangeEvent(change); 40 | } 41 | 42 | void DistantLight::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 43 | { 44 | const auto typedChange = qSharedPointerCast>(change); 45 | const auto &data = typedChange->data; 46 | 47 | m_color = data.color; 48 | m_intensity = qMax(data.intensity, 0.0f); 49 | m_direction = data.direction; 50 | 51 | markDirty(AbstractRenderer::LightDirty); 52 | } 53 | 54 | } // Raytrace 55 | } // Qt3DRaytrace 56 | -------------------------------------------------------------------------------- /src/raytrace/backend/distantlight_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Raytrace { 18 | 19 | class DistantLightManager; 20 | 21 | class DistantLight : public BackendNode 22 | { 23 | public: 24 | DistantLight(); 25 | 26 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 27 | 28 | LinearColor radiance() const 29 | { 30 | return LinearColor::from_sRgb(m_color, m_intensity); 31 | } 32 | QVector3D direction() const 33 | { 34 | return m_direction; 35 | } 36 | 37 | private: 38 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 39 | 40 | QColor m_color; 41 | float m_intensity; 42 | QVector3D m_direction; 43 | }; 44 | 45 | } // Raytrace 46 | } // Qt3DRaytrace 47 | -------------------------------------------------------------------------------- /src/raytrace/backend/geometry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace Qt3DCore; 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Raytrace { 17 | 18 | void Geometry::setManager(GeometryManager *manager) 19 | { 20 | Q_ASSERT(manager); 21 | m_manager = manager; 22 | } 23 | 24 | void Geometry::sceneChangeEvent(const QSceneChangePtr &change) 25 | { 26 | if(change->type() == PropertyUpdated) { 27 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 28 | if(propertyChange->propertyName() == QByteArrayLiteral("data")) { 29 | m_data = propertyChange->value().value(); 30 | if(m_manager) { 31 | m_manager->markComponentDirty(peerId()); 32 | } 33 | markDirty(AbstractRenderer::GeometryDirty); 34 | } 35 | } 36 | BackendNode::sceneChangeEvent(change); 37 | } 38 | 39 | void Geometry::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 40 | { 41 | const auto typedChange = qSharedPointerCast>(change); 42 | m_data = typedChange->data; 43 | 44 | if(m_manager) { 45 | m_manager->markComponentDirty(peerId()); 46 | } 47 | markDirty(AbstractRenderer::GeometryDirty); 48 | } 49 | 50 | } // Raytrace 51 | } // Qt3DRaytrace 52 | -------------------------------------------------------------------------------- /src/raytrace/backend/geometry_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | class GeometryManager; 18 | 19 | class Geometry : public BackendNode 20 | { 21 | public: 22 | const QGeometryData &data() const { return m_data; } 23 | const QVector &vertices() const { return m_data.vertices; } 24 | const QVector &faces() const { return m_data.faces; } 25 | 26 | void setManager(GeometryManager *manager); 27 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 28 | 29 | private: 30 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 31 | 32 | GeometryManager *m_manager = nullptr; 33 | QGeometryData m_data; 34 | }; 35 | 36 | class GeometryNodeMapper final : public BackendNodeMapper 37 | { 38 | public: 39 | GeometryNodeMapper(GeometryManager *manager, AbstractRenderer *renderer) 40 | : BackendNodeMapper(manager, renderer) 41 | {} 42 | 43 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 44 | { 45 | auto geometry = static_cast(BackendNodeMapper::create(change)); 46 | geometry->setManager(m_manager); 47 | return geometry; 48 | } 49 | }; 50 | 51 | } // Raytrace 52 | } // Qt3DRaytrace 53 | -------------------------------------------------------------------------------- /src/raytrace/backend/geometryrenderer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | using namespace Qt3DCore; 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Raytrace { 18 | 19 | GeometryRenderer::GeometryRenderer() 20 | : BackendNode(ReadWrite) 21 | , m_manager(nullptr) 22 | {} 23 | 24 | void GeometryRenderer::setManager(GeometryRendererManager *manager) 25 | { 26 | Q_ASSERT(manager); 27 | m_manager = manager; 28 | } 29 | 30 | void GeometryRenderer::sceneChangeEvent(const QSceneChangePtr &change) 31 | { 32 | if(change->type() == PropertyUpdated) { 33 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 34 | const auto propertyName = propertyChange->propertyName(); 35 | if(propertyName == QByteArrayLiteral("geometry")) { 36 | m_geometryId = propertyChange->value().value(); 37 | } 38 | else if(propertyName == QByteArrayLiteral("geometryFactory")) { 39 | m_geometryFactory = propertyChange->value().value(); 40 | if(m_geometryFactory && m_manager) { 41 | m_manager->markComponentDirty(peerId()); 42 | } 43 | } 44 | } 45 | 46 | markDirty(AbstractRenderer::GeometryDirty); 47 | BackendNode::sceneChangeEvent(change); 48 | } 49 | 50 | void GeometryRenderer::loadGeometry() 51 | { 52 | Q_ASSERT(m_geometryFactory); 53 | 54 | std::unique_ptr geometry(m_geometryFactory->create()); 55 | if(geometry) { 56 | geometry->moveToThread(QCoreApplication::instance()->thread()); 57 | 58 | auto change = QGeometryChangePtr::create(peerId()); 59 | change->setDeliveryFlags(QSceneChange::Nodes); 60 | change->setPropertyName("geometry"); 61 | change->data = std::move(geometry); 62 | notifyObservers(change); 63 | } 64 | } 65 | 66 | void GeometryRenderer::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 67 | { 68 | const auto typedChange = qSharedPointerCast>(change); 69 | const auto &data = typedChange->data; 70 | 71 | m_geometryId = data.geometryId; 72 | m_geometryFactory = data.geometryFactory; 73 | if(m_geometryFactory && m_manager) { 74 | m_manager->markComponentDirty(peerId()); 75 | } 76 | 77 | markDirty(AbstractRenderer::GeometryDirty); 78 | } 79 | 80 | } // Raytrace 81 | } // Qt3DRaytrace 82 | -------------------------------------------------------------------------------- /src/raytrace/backend/geometryrenderer_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Raytrace { 15 | 16 | class GeometryRendererManager; 17 | 18 | class GeometryRenderer : public BackendNode 19 | { 20 | public: 21 | GeometryRenderer(); 22 | 23 | void setManager(GeometryRendererManager *manager); 24 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 25 | void loadGeometry(); 26 | 27 | Qt3DCore::QNodeId geometryId() const { return m_geometryId; } 28 | QGeometryFactoryPtr geometryFactory() const { return m_geometryFactory; } 29 | 30 | private: 31 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 32 | 33 | GeometryRendererManager *m_manager; 34 | Qt3DCore::QNodeId m_geometryId; 35 | QGeometryFactoryPtr m_geometryFactory; 36 | }; 37 | 38 | class GeometryRendererNodeMapper final : public BackendNodeMapper 39 | { 40 | public: 41 | GeometryRendererNodeMapper(GeometryRendererManager *manager, AbstractRenderer *renderer) 42 | : BackendNodeMapper(manager, renderer) 43 | {} 44 | 45 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 46 | { 47 | auto geometryRenderer = static_cast(BackendNodeMapper::create(change)); 48 | geometryRenderer->setManager(m_manager); 49 | return geometryRenderer; 50 | } 51 | }; 52 | 53 | } // Raytrace 54 | } // Qt3DRaytrace 55 | -------------------------------------------------------------------------------- /src/raytrace/backend/handles_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | using HEntity = Qt3DCore::QHandle; 16 | using HTransform = Qt3DCore::QHandle; 17 | using HGeometry = Qt3DCore::QHandle; 18 | using HGeometryRenderer = Qt3DCore::QHandle; 19 | using HTextureImage = Qt3DCore::QHandle; 20 | using HAbstractTexture = Qt3DCore::QHandle; 21 | using HMaterial = Qt3DCore::QHandle; 22 | 23 | } // Raytrace 24 | } // Qt3DRaytrace 25 | -------------------------------------------------------------------------------- /src/raytrace/backend/managers_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | #include 22 | 23 | namespace Qt3DRaytrace { 24 | namespace Raytrace { 25 | 26 | class EntityManager : public Qt3DCore::QResourceManager 27 | { 28 | public: 29 | ~EntityManager() 30 | { 31 | Allocator::for_each([](Entity *e) { 32 | if(e) { 33 | e->m_nodeManagers = nullptr; 34 | } 35 | }); 36 | } 37 | }; 38 | 39 | template class LockingPolicy = Qt3DCore::NonLockingPolicy> 40 | class ComponentManager : public Qt3DCore::QResourceManager 41 | { 42 | public: 43 | void markComponentDirty(Qt3DCore::QNodeId componentId) 44 | { 45 | if(!m_dirtyComponents.contains(componentId)) { 46 | m_dirtyComponents.append(componentId); 47 | } 48 | } 49 | QVector acquireDirtyComponents() 50 | { 51 | QVector result(std::move(m_dirtyComponents)); 52 | return result; 53 | } 54 | void clearDirtyComponents() 55 | { 56 | m_dirtyComponents.clear(); 57 | } 58 | 59 | private: 60 | QVector m_dirtyComponents; 61 | }; 62 | 63 | class TransformManager : public Qt3DCore::QResourceManager {}; 64 | class GeometryManager : public ComponentManager {}; 65 | class GeometryRendererManager : public ComponentManager {}; 66 | class TextureManager : public ComponentManager {}; 67 | class TextureImageManager : public ComponentManager {}; 68 | class MaterialManager : public ComponentManager {}; 69 | class DistantLightManager : public ComponentManager {}; 70 | class CameraManager : public ComponentManager {}; 71 | 72 | struct NodeManagers 73 | { 74 | EntityManager entityManager; 75 | TransformManager transformManager; 76 | GeometryManager geometryManager; 77 | GeometryRendererManager geometryRendererManager; 78 | TextureManager textureManager; 79 | TextureImageManager textureImageManager; 80 | MaterialManager materialManager; 81 | DistantLightManager distantLightManager; 82 | CameraManager cameraManager; 83 | }; 84 | 85 | } // Raytrace 86 | } // Qt3DRaytrace 87 | -------------------------------------------------------------------------------- /src/raytrace/backend/material.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace Qt3DCore; 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Raytrace { 17 | 18 | Material::Material() 19 | : BackendNode(ReadOnly) 20 | {} 21 | 22 | void Material::setManager(MaterialManager *manager) 23 | { 24 | Q_ASSERT(manager); 25 | m_manager = manager; 26 | } 27 | 28 | void Material::sceneChangeEvent(const QSceneChangePtr &change) 29 | { 30 | if(change->type() == PropertyUpdated) { 31 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 32 | const auto propertyName = propertyChange->propertyName(); 33 | if(propertyName == QByteArrayLiteral("albedo")) { 34 | m_albedo = propertyChange->value().value(); 35 | } 36 | else if(propertyName == QByteArrayLiteral("roughness")) { 37 | m_roughness = qBound(0.0f, propertyChange->value().value(), 1.0f); 38 | } 39 | else if(propertyName == QByteArrayLiteral("metalness")) { 40 | m_metalness = qBound(0.0f, propertyChange->value().value(), 1.0f); 41 | } 42 | else if(propertyName == QByteArrayLiteral("emission")) { 43 | m_emission = propertyChange->value().value(); 44 | } 45 | else if(propertyName == QByteArrayLiteral("emissionIntensity")) { 46 | m_emissionIntensity = qMax(propertyChange->value().value(), 0.0f); 47 | } 48 | else if(propertyName == QByteArrayLiteral("albedoTexture")) { 49 | m_albedoTextureId = propertyChange->value().value(); 50 | } 51 | else if(propertyName == QByteArrayLiteral("roughnessTexture")) { 52 | m_roughnessTextureId = propertyChange->value().value(); 53 | } 54 | else if(propertyName == QByteArrayLiteral("metalnessTexture")) { 55 | m_metalnessTextureId = propertyChange->value().value(); 56 | } 57 | 58 | if(m_manager) { 59 | m_manager->markComponentDirty(peerId()); 60 | } 61 | } 62 | 63 | markDirty(AbstractRenderer::MaterialDirty); 64 | BackendNode::sceneChangeEvent(change); 65 | } 66 | 67 | void Material::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 68 | { 69 | const auto typedChange = qSharedPointerCast>(change); 70 | const auto &data = typedChange->data; 71 | 72 | m_albedo = data.albedo; 73 | m_roughness = qBound(0.0f, data.roughness, 1.0f); 74 | m_metalness = qBound(0.0f, data.metalness, 1.0f); 75 | m_emission = data.emission; 76 | m_emissionIntensity = qMax(data.emissionIntensity, 0.0f); 77 | 78 | m_albedoTextureId = data.albedoTextureId; 79 | m_roughnessTextureId = data.roughnessTextureId; 80 | m_metalnessTextureId = data.metalnessTextureId; 81 | 82 | if(m_manager) { 83 | m_manager->markComponentDirty(peerId()); 84 | } 85 | 86 | markDirty(AbstractRenderer::MaterialDirty); 87 | } 88 | 89 | } // Raytrace 90 | } // Qt3DRaytrace 91 | -------------------------------------------------------------------------------- /src/raytrace/backend/material_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Raytrace { 15 | 16 | class MaterialManager; 17 | 18 | class Material : public BackendNode 19 | { 20 | public: 21 | Material(); 22 | 23 | void setManager(MaterialManager *manager); 24 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 25 | 26 | LinearColor albedo() const 27 | { 28 | return LinearColor::from_sRgb(m_albedo); 29 | } 30 | float roughness() const 31 | { 32 | return m_roughness; 33 | } 34 | float metalness() const 35 | { 36 | return m_metalness; 37 | } 38 | LinearColor emission() const 39 | { 40 | return LinearColor::from_sRgb(m_emission, m_emissionIntensity); 41 | } 42 | 43 | Qt3DCore::QNodeId albedoTextureId() const 44 | { 45 | return m_albedoTextureId; 46 | } 47 | Qt3DCore::QNodeId roughnessTextureId() const 48 | { 49 | return m_roughnessTextureId; 50 | } 51 | Qt3DCore::QNodeId metalnessTextureId() const 52 | { 53 | return m_metalnessTextureId; 54 | } 55 | 56 | private: 57 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 58 | 59 | MaterialManager *m_manager; 60 | 61 | QColor m_albedo; 62 | float m_roughness; 63 | float m_metalness; 64 | QColor m_emission; 65 | float m_emissionIntensity; 66 | 67 | Qt3DCore::QNodeId m_albedoTextureId; 68 | Qt3DCore::QNodeId m_roughnessTextureId; 69 | Qt3DCore::QNodeId m_metalnessTextureId; 70 | }; 71 | 72 | class MaterialNodeMapper final : public BackendNodeMapper 73 | { 74 | public: 75 | MaterialNodeMapper(MaterialManager *manager, AbstractRenderer *renderer) 76 | : BackendNodeMapper(manager, renderer) 77 | {} 78 | 79 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 80 | { 81 | auto material = static_cast(BackendNodeMapper::create(change)); 82 | material->setManager(m_manager); 83 | return material; 84 | } 85 | }; 86 | 87 | } // Raytrace 88 | } // Qt3DRaytrace 89 | -------------------------------------------------------------------------------- /src/raytrace/backend/rendersettings_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Raytrace { 18 | 19 | class RenderSettings : public BackendNode 20 | { 21 | public: 22 | RenderSettings(); 23 | 24 | Qt3DCore::QNodeId cameraId() const { return m_cameraId; } 25 | unsigned int primarySamples() const { return m_primarySamples; } 26 | unsigned int secondarySamples() const { return m_secondarySamples; } 27 | unsigned int minDepth() const { return m_minDepth; } 28 | unsigned int maxDepth() const { return m_maxDepth; } 29 | 30 | float directRadianceClamp() const; 31 | float indirectRadianceClamp() const; 32 | 33 | LinearColor skyRadiance() const 34 | { 35 | return LinearColor::from_sRgb(m_skyColor, m_skyIntensity); 36 | } 37 | 38 | float skyIntensity() const { return m_skyIntensity; } 39 | Qt3DCore::QNodeId skyTextureId() const { return m_skyTextureId; } 40 | QVector2D skyTextureOffset() const { return m_skyTextureOffset; } 41 | 42 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 43 | 44 | private: 45 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 46 | 47 | Qt3DCore::QNodeId m_cameraId; 48 | unsigned int m_primarySamples; 49 | unsigned int m_secondarySamples; 50 | unsigned int m_minDepth; 51 | unsigned int m_maxDepth; 52 | float m_directRadianceClamp; 53 | float m_indirectRadianceClamp; 54 | QColor m_skyColor; 55 | float m_skyIntensity; 56 | Qt3DCore::QNodeId m_skyTextureId; 57 | QVector2D m_skyTextureOffset; 58 | }; 59 | 60 | class RenderSettingsMapper final : public Qt3DCore::QBackendNodeMapper 61 | { 62 | public: 63 | explicit RenderSettingsMapper(AbstractRenderer *renderer) 64 | : m_renderer(renderer) 65 | { 66 | Q_ASSERT(m_renderer); 67 | } 68 | 69 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override; 70 | Qt3DCore::QBackendNode *get(Qt3DCore::QNodeId id) const override; 71 | void destroy(Qt3DCore::QNodeId id) const override; 72 | 73 | private: 74 | AbstractRenderer *m_renderer; 75 | }; 76 | 77 | } // Raytrace 78 | } // Qt3DRaytrace 79 | -------------------------------------------------------------------------------- /src/raytrace/backend/textureimage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | using namespace Qt3DCore; 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Raytrace { 17 | 18 | void TextureImage::setManager(TextureImageManager *manager) 19 | { 20 | Q_ASSERT(manager); 21 | m_manager = manager; 22 | } 23 | 24 | void TextureImage::sceneChangeEvent(const QSceneChangePtr &change) 25 | { 26 | if(change->type() == PropertyUpdated) { 27 | QPropertyUpdatedChangePtr propertyChange = qSharedPointerCast(change); 28 | if(propertyChange->propertyName() == QByteArrayLiteral("data")) { 29 | m_data = propertyChange->value().value(); 30 | if(m_manager) { 31 | m_manager->markComponentDirty(peerId()); 32 | } 33 | markDirty(AbstractRenderer::TextureDirty); 34 | } 35 | } 36 | BackendNode::sceneChangeEvent(change); 37 | } 38 | 39 | void TextureImage::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 40 | { 41 | const auto typedChange = qSharedPointerCast>(change); 42 | m_data = typedChange->data; 43 | 44 | if(m_manager) { 45 | m_manager->markComponentDirty(peerId()); 46 | } 47 | markDirty(AbstractRenderer::TextureDirty); 48 | } 49 | 50 | } // Raytrace 51 | } // Qt3DRaytrace 52 | -------------------------------------------------------------------------------- /src/raytrace/backend/textureimage_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | class TextureImageManager; 18 | 19 | class TextureImage : public BackendNode 20 | { 21 | public: 22 | const QImageData &data() const { return m_data; } 23 | 24 | void setManager(TextureImageManager *manager); 25 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &change) override; 26 | 27 | private: 28 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 29 | 30 | TextureImageManager *m_manager = nullptr; 31 | QImageData m_data; 32 | }; 33 | 34 | class TextureImageNodeMapper final : public BackendNodeMapper 35 | { 36 | public: 37 | TextureImageNodeMapper(TextureImageManager *manager, AbstractRenderer *renderer) 38 | : BackendNodeMapper(manager, renderer) 39 | {} 40 | 41 | Qt3DCore::QBackendNode *create(const Qt3DCore::QNodeCreatedChangeBasePtr &change) const override 42 | { 43 | auto textureImage = static_cast(BackendNodeMapper::create(change)); 44 | textureImage->setManager(m_manager); 45 | return textureImage; 46 | } 47 | }; 48 | 49 | } // Raytrace 50 | } // Qt3DRaytrace 51 | -------------------------------------------------------------------------------- /src/raytrace/backend/transform.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | Transform::Transform() 16 | { 17 | m_transform.scale = { 1.0f, 1.0f, 1.0f }; 18 | } 19 | 20 | void Transform::initializeFromPeer(const QNodeCreatedChangeBasePtr &change) 21 | { 22 | const auto typedChange = qSharedPointerCast>(change); 23 | m_transform = typedChange->data; 24 | updateTransformMatrix(); 25 | } 26 | 27 | void Transform::sceneChangeEvent(const QSceneChangePtr &change) 28 | { 29 | if(change->type() == PropertyUpdated) { 30 | const QPropertyUpdatedChangePtr &propertyChange = qSharedPointerCast(change); 31 | if(propertyChange->propertyName() == QByteArrayLiteral("translation")) { 32 | m_transform.translation = propertyChange->value().value(); 33 | updateTransformMatrix(); 34 | } 35 | else if(propertyChange->propertyName() == QByteArrayLiteral("rotation")) { 36 | m_transform.rotation = propertyChange->value().value(); 37 | updateTransformMatrix(); 38 | } 39 | else if(propertyChange->propertyName() == QByteArrayLiteral("scale3D")) { 40 | m_transform.scale = propertyChange->value().value(); 41 | updateTransformMatrix(); 42 | } 43 | markDirty(AbstractRenderer::TransformDirty); 44 | } 45 | BackendNode::sceneChangeEvent(change); 46 | } 47 | 48 | void Transform::updateTransformMatrix() 49 | { 50 | QMatrix4x4 m; 51 | m.translate(m_transform.translation); 52 | m.rotate(m_transform.rotation); 53 | m.scale(m_transform.scale); 54 | m_transformMatrix = Matrix4x4(m); 55 | } 56 | 57 | } // Raytrace 58 | } // Qt3DRaytrace 59 | 60 | -------------------------------------------------------------------------------- /src/raytrace/backend/transform_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace Qt3DRaytrace { 19 | namespace Raytrace { 20 | 21 | class Transform : public BackendNode 22 | { 23 | public: 24 | Transform(); 25 | 26 | Matrix4x4 transformMatrix() const { return m_transformMatrix; } 27 | 28 | protected: 29 | void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) override; 30 | 31 | private: 32 | void initializeFromPeer(const Qt3DCore::QNodeCreatedChangeBasePtr &change) override; 33 | void updateTransformMatrix(); 34 | 35 | Qt3DCore::QTransformData m_transform; 36 | Matrix4x4 m_transformMatrix; 37 | }; 38 | 39 | } // Raytrace 40 | } // Qt3DRaytrace 41 | -------------------------------------------------------------------------------- /src/raytrace/backend/types_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | struct LinearColor 16 | { 17 | LinearColor() 18 | : r(0.0f), g(0.0f), b(0.0f) 19 | {} 20 | LinearColor(float r, float g, float b) 21 | : r(r), g(g), b(b) 22 | {} 23 | LinearColor(const QColor &c, float intensity=1.0f) 24 | : r(float(c.redF()) * intensity) 25 | , g(float(c.greenF()) * intensity) 26 | , b(float(c.blueF()) * intensity) 27 | {} 28 | 29 | static LinearColor from_sRgb(const QColor &c, float intensity=1.0f) 30 | { 31 | return LinearColor(to_linearRgb(c), intensity); 32 | } 33 | 34 | bool isBlack() const 35 | { 36 | float maxComponent = std::max(std::max(r, g), b); 37 | return qFuzzyIsNull(maxComponent); 38 | } 39 | 40 | void writeToBuffer(float *buffer) const 41 | { 42 | buffer[0] = r; 43 | buffer[1] = g; 44 | buffer[2] = b; 45 | } 46 | 47 | float r, g, b; 48 | }; 49 | 50 | } // Raytrace 51 | } // Qt3DRaytrace 52 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qabstracttexture.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | QAbstractTexture::QAbstractTexture(QNode *parent) 15 | : QNode(*new QAbstractTexturePrivate, parent) 16 | {} 17 | 18 | QAbstractTexture::QAbstractTexture(QAbstractTexturePrivate &dd, QNode *parent) 19 | : QNode(dd, parent) 20 | {} 21 | 22 | QTextureImage *QAbstractTexture::image() const 23 | { 24 | Q_D(const QAbstractTexture); 25 | return d->m_image; 26 | } 27 | 28 | QTextureImageFactoryPtr QAbstractTexture::imageFactory() const 29 | { 30 | Q_D(const QAbstractTexture); 31 | return d->m_imageFactory; 32 | } 33 | 34 | void QAbstractTexture::setImageFactory(const QTextureImageFactoryPtr &factory) 35 | { 36 | Q_D(QAbstractTexture); 37 | d->m_imageFactory = factory; 38 | if(d->m_changeArbiter) { 39 | auto change = QPropertyUpdatedChangePtr::create(d->m_id); 40 | change->setPropertyName("imageFactory"); 41 | change->setValue(QVariant::fromValue(d->m_imageFactory)); 42 | d->notifyObservers(change); 43 | } 44 | } 45 | 46 | void QAbstractTexture::setImage(QTextureImage *image) 47 | { 48 | Q_D(QAbstractTexture); 49 | if(d->m_image != image) { 50 | if(d->m_image) { 51 | d->unregisterDestructionHelper(d->m_image); 52 | } 53 | d->m_image = image; 54 | if(d->m_image) { 55 | if(!d->m_image->parent()) { 56 | d->m_image->setParent(this); 57 | } 58 | d->registerDestructionHelper(d->m_image, &QAbstractTexture::setImage, d->m_image); 59 | } 60 | emit imageChanged(d->m_image); 61 | } 62 | } 63 | 64 | void QAbstractTexture::sceneChangeEvent(const QSceneChangePtr &change) 65 | { 66 | if(change->type() == PropertyUpdated) { 67 | auto propertyChange = qSharedPointerCast(change); 68 | if(propertyChange->propertyName() == QByteArrayLiteral("image")) { 69 | auto typedChange = qSharedPointerCast(change); 70 | setImage(typedChange->data.release()); 71 | } 72 | } 73 | } 74 | 75 | QNodeCreatedChangeBasePtr QAbstractTexture::createNodeCreationChange() const 76 | { 77 | Q_D(const QAbstractTexture); 78 | auto creationChange = QNodeCreatedChangePtr::create(this); 79 | auto &data = creationChange->data; 80 | data.imageId = qIdForNode(d->m_image); 81 | data.imageFactory = d->m_imageFactory; 82 | return creationChange; 83 | } 84 | 85 | } // Qt3DRaytrace 86 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qabstracttexture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QAbstractTexturePrivate : public Qt3DCore::QNodePrivate 18 | { 19 | public: 20 | Q_DECLARE_PUBLIC(QAbstractTexture) 21 | QTextureImage *m_image = nullptr; 22 | QTextureImageFactoryPtr m_imageFactory; 23 | }; 24 | 25 | struct QTextureData 26 | { 27 | Qt3DCore::QNodeId imageId; 28 | QTextureImageFactoryPtr imageFactory; 29 | }; 30 | 31 | class QTextureImage; 32 | 33 | // TODO: Is std::unique_ptr really needed here? 34 | using QTextureImageChange = Qt3DCore::QTypedPropertyUpdatedChange>; 35 | using QTextureImageChangePtr = Qt3DCore::QTypedPropertyUpdatedChangePtr>; 36 | 37 | } // Qt3DRaytrace 38 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qcamera_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DCore { 13 | class QTransform; 14 | } // Qt3DCore 15 | 16 | namespace Qt3DRaytrace { 17 | 18 | class QCameraLens; 19 | 20 | class QCameraPrivate : public Qt3DCore::QEntityPrivate 21 | { 22 | public: 23 | QCameraPrivate(); 24 | Q_DECLARE_PUBLIC(QCamera) 25 | 26 | void updateRotation(const QQuaternion &rotation, bool updateEulerAngles); 27 | void updateLookAtRotation(); 28 | 29 | QCameraLens *m_lens; 30 | Qt3DCore::QTransform *m_transform; 31 | 32 | QVector3D m_position; 33 | QQuaternion m_rotation; 34 | QVector3D m_eulerAngles; 35 | QVector3D m_lookAtTarget; 36 | QVector3D m_lookAtUp; 37 | }; 38 | 39 | } // Qt3DRaytrace 40 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qcameralens_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | struct QCameraLensData 15 | { 16 | float aspectRatio = 1.0f; 17 | float fieldOfView = 90.0f; 18 | float diameter = 0.0f; 19 | float focalDistance = 1.0f; 20 | float gamma = 2.2f; 21 | float exposure = 1.0f; 22 | float tonemapFactor = 1.0f; 23 | }; 24 | 25 | class QCameraLensPrivate : public Qt3DCore::QComponentPrivate 26 | { 27 | public: 28 | Q_DECLARE_PUBLIC(QCameraLens) 29 | QCameraLensData m_data; 30 | }; 31 | 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qdistantlight.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | 9 | using namespace Qt3DCore; 10 | 11 | namespace Qt3DRaytrace { 12 | 13 | QDistantLight::QDistantLight(QNode *parent) 14 | : QComponent(*new QDistantLightPrivate, parent) 15 | {} 16 | 17 | QColor QDistantLight::color() const 18 | { 19 | Q_D(const QDistantLight); 20 | return d->m_data.color; 21 | } 22 | 23 | float QDistantLight::intensity() const 24 | { 25 | Q_D(const QDistantLight); 26 | return d->m_data.intensity; 27 | } 28 | 29 | QVector3D QDistantLight::direction() const 30 | { 31 | Q_D(const QDistantLight); 32 | return d->m_data.direction; 33 | } 34 | 35 | void QDistantLight::setColor(const QColor &color) 36 | { 37 | Q_D(QDistantLight); 38 | if(d->m_data.color != color) { 39 | d->m_data.color = color; 40 | emit colorChanged(color); 41 | } 42 | } 43 | 44 | void QDistantLight::setIntensity(float intensity) 45 | { 46 | Q_D(QDistantLight); 47 | if(!qFuzzyCompare(d->m_data.intensity, intensity)) { 48 | d->m_data.intensity = intensity; 49 | emit intensityChanged(intensity); 50 | } 51 | } 52 | 53 | void QDistantLight::setDirection(const QVector3D &direction) 54 | { 55 | Q_D(QDistantLight); 56 | const QVector3D normalizedDirection = direction.normalized(); 57 | if(!qFuzzyCompare(d->m_data.direction, normalizedDirection)) { 58 | d->m_data.direction = normalizedDirection; 59 | emit directionChanged(normalizedDirection); 60 | } 61 | } 62 | 63 | QDistantLight::QDistantLight(QDistantLightPrivate &dd, QNode *parent) 64 | : QComponent(dd, parent) 65 | {} 66 | 67 | QNodeCreatedChangeBasePtr QDistantLight::createNodeCreationChange() const 68 | { 69 | Q_D(const QDistantLight); 70 | 71 | auto creationChange = QNodeCreatedChangePtr::create(this); 72 | creationChange->data = d->m_data; 73 | return creationChange; 74 | } 75 | 76 | } // Qt3DRaytrace 77 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qdistantlight_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | struct QLightData 16 | { 17 | QColor color = Qt::GlobalColor::white; 18 | float intensity = 1.0f; 19 | QVector3D direction{0.0f, -1.0f, 0.0f}; 20 | }; 21 | 22 | class QDistantLightPrivate : public Qt3DCore::QComponentPrivate 23 | { 24 | public: 25 | Q_DECLARE_PUBLIC(QDistantLight) 26 | QLightData m_data; 27 | }; 28 | 29 | } // Qt3DRaytrace 30 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qgeometry.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | 9 | using namespace Qt3DCore; 10 | 11 | namespace Qt3DRaytrace { 12 | 13 | QGeometry::QGeometry(QNode *parent) 14 | : QNode(*new QGeometryPrivate, parent) 15 | {} 16 | 17 | const QGeometryData &QGeometry::data() const 18 | { 19 | Q_D(const QGeometry); 20 | return d->m_data; 21 | } 22 | 23 | const QVector &QGeometry::vertices() const 24 | { 25 | Q_D(const QGeometry); 26 | return d->m_data.vertices; 27 | } 28 | 29 | const QVector &QGeometry::faces() const 30 | { 31 | Q_D(const QGeometry); 32 | return d->m_data.faces; 33 | } 34 | 35 | void QGeometry::setData(const QGeometryData &geometryData) 36 | { 37 | Q_D(QGeometry); 38 | d->m_data = geometryData; 39 | QNodePrivate::get(this)->notifyPropertyChange("data", QVariant::fromValue(d->m_data)); 40 | emit dataChanged(d->m_data); 41 | } 42 | 43 | void QGeometry::clearData() 44 | { 45 | setData(QGeometryData()); 46 | } 47 | 48 | QGeometry::QGeometry(QGeometryPrivate &dd, QNode *parent) 49 | : QNode(dd, parent) 50 | {} 51 | 52 | QNodeCreatedChangeBasePtr QGeometry::createNodeCreationChange() const 53 | { 54 | Q_D(const QGeometry); 55 | auto creationChange = QNodeCreatedChangePtr::create(this); 56 | creationChange->data = d->m_data; 57 | return creationChange; 58 | } 59 | 60 | } // Qt3DRaytrace 61 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qgeometry_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | class QGeometryPrivate : public Qt3DCore::QNodePrivate 16 | { 17 | public: 18 | Q_DECLARE_PUBLIC(QGeometry) 19 | QGeometryData m_data; 20 | }; 21 | 22 | } // Qt3DRaytrace 23 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qgeometryrenderer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | QGeometryRenderer::QGeometryRenderer(QNode *parent) 15 | : QComponent(*new QGeometryRendererPrivate, parent) 16 | {} 17 | 18 | QGeometryRenderer::QGeometryRenderer(QGeometryRendererPrivate &dd, QNode *parent) 19 | : QComponent(dd, parent) 20 | {} 21 | 22 | QGeometry *QGeometryRenderer::geometry() const 23 | { 24 | Q_D(const QGeometryRenderer); 25 | return d->m_geometry; 26 | } 27 | 28 | QGeometryFactoryPtr QGeometryRenderer::geometryFactory() const 29 | { 30 | Q_D(const QGeometryRenderer); 31 | return d->m_geometryFactory; 32 | } 33 | 34 | void QGeometryRenderer::setGeometryFactory(const QGeometryFactoryPtr &factory) 35 | { 36 | Q_D(QGeometryRenderer); 37 | d->m_geometryFactory = factory; 38 | if(d->m_changeArbiter) { 39 | auto change = QPropertyUpdatedChangePtr::create(d->m_id); 40 | change->setPropertyName("geometryFactory"); 41 | change->setValue(QVariant::fromValue(d->m_geometryFactory)); 42 | d->notifyObservers(change); 43 | } 44 | } 45 | 46 | void QGeometryRenderer::setGeometry(QGeometry *geometry) 47 | { 48 | Q_D(QGeometryRenderer); 49 | if(d->m_geometry != geometry) { 50 | if(d->m_geometry) { 51 | d->unregisterDestructionHelper(d->m_geometry); 52 | } 53 | d->m_geometry = geometry; 54 | if(d->m_geometry) { 55 | if(!d->m_geometry->parent()) { 56 | d->m_geometry->setParent(this); 57 | } 58 | d->registerDestructionHelper(d->m_geometry, &QGeometryRenderer::setGeometry, d->m_geometry); 59 | } 60 | emit geometryChanged(d->m_geometry); 61 | } 62 | } 63 | 64 | void QGeometryRenderer::sceneChangeEvent(const QSceneChangePtr &change) 65 | { 66 | if(change->type() == PropertyUpdated) { 67 | auto propertyChange = qSharedPointerCast(change); 68 | if(propertyChange->propertyName() == QByteArrayLiteral("geometry")) { 69 | auto typedChange = qSharedPointerCast(change); 70 | setGeometry(typedChange->data.release()); 71 | } 72 | } 73 | } 74 | 75 | QNodeCreatedChangeBasePtr QGeometryRenderer::createNodeCreationChange() const 76 | { 77 | Q_D(const QGeometryRenderer); 78 | auto creationChange = QNodeCreatedChangePtr::create(this); 79 | auto &data = creationChange->data; 80 | data.geometryId = qIdForNode(d->m_geometry); 81 | data.geometryFactory = d->m_geometryFactory; 82 | return creationChange; 83 | } 84 | 85 | } // Qt3DRaytrace 86 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qgeometryrenderer_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | class QGeometryRendererPrivate : public Qt3DCore::QComponentPrivate 18 | { 19 | public: 20 | Q_DECLARE_PUBLIC(QGeometryRenderer) 21 | QGeometry *m_geometry = nullptr; 22 | QGeometryFactoryPtr m_geometryFactory; 23 | }; 24 | 25 | struct QGeometryRendererData 26 | { 27 | Qt3DCore::QNodeId geometryId; 28 | QGeometryFactoryPtr geometryFactory; 29 | }; 30 | 31 | class QGeometry; 32 | 33 | // TODO: Is std::unique_ptr really needed here? 34 | using QGeometryChange = Qt3DCore::QTypedPropertyUpdatedChange>; 35 | using QGeometryChangePtr = Qt3DCore::QTypedPropertyUpdatedChangePtr>; 36 | 37 | } // Qt3DRaytrace 38 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qmaterial_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | struct QMaterialData 16 | { 17 | QColor albedo; 18 | float roughness; 19 | float metalness; 20 | QColor emission; 21 | float emissionIntensity; 22 | Qt3DCore::QNodeId albedoTextureId; 23 | Qt3DCore::QNodeId roughnessTextureId; 24 | Qt3DCore::QNodeId metalnessTextureId; 25 | }; 26 | 27 | class QMaterialPrivate : public Qt3DCore::QComponentPrivate 28 | { 29 | public: 30 | Q_DECLARE_PUBLIC(QMaterial) 31 | 32 | QColor m_albedo = Qt::GlobalColor::gray; 33 | float m_roughness = 1.0f; 34 | float m_metalness = 0.0f; 35 | QColor m_emission = Qt::GlobalColor::white; 36 | float m_emissionIntensity = 0.0f; 37 | QAbstractTexture *m_albedoTexture = nullptr; 38 | QAbstractTexture *m_roughnessTexture = nullptr; 39 | QAbstractTexture *m_metalnessTexture = nullptr; 40 | }; 41 | 42 | } // Qt3DRaytrace 43 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qmesh.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | // TODO: Implement status change. 15 | // TODO: Make mesh importer configurable. 16 | 17 | QMesh::QMesh(QNode *parent) 18 | : QGeometryRenderer(*new QMeshPrivate, parent) 19 | {} 20 | 21 | QMesh::QMesh(QMeshPrivate &dd, QNode *parent) 22 | : QGeometryRenderer(dd, parent) 23 | {} 24 | 25 | QUrl QMesh::source() const 26 | { 27 | Q_D(const QMesh); 28 | return d->m_source; 29 | } 30 | 31 | QMesh::Status QMesh::status() const 32 | { 33 | Q_D(const QMesh); 34 | return d->m_status; 35 | } 36 | 37 | void QMesh::setSource(const QUrl &source) 38 | { 39 | Q_D(QMesh); 40 | if(d->m_source != source) { 41 | d->m_source = source; 42 | setGeometryFactory(QGeometryFactoryPtr(new MeshLoader(this))); 43 | emit sourceChanged(source); 44 | } 45 | } 46 | 47 | MeshLoader::MeshLoader(const QMesh *mesh) 48 | : m_importer(new Raytrace::DefaultMeshImporter) 49 | , m_source(mesh->source()) 50 | {} 51 | 52 | QGeometry *MeshLoader::create() 53 | { 54 | Q_ASSERT(m_importer); 55 | 56 | if(m_source.isEmpty()) { 57 | qCWarning(logImport) << "Mesh source path is empty"; 58 | return nullptr; 59 | } 60 | 61 | QGeometryData geometryData; 62 | if(m_importer->import(m_source, geometryData)) { 63 | QGeometry *geometry = new QGeometry; 64 | geometry->setData(geometryData); 65 | return geometry; 66 | } 67 | else { 68 | return nullptr; 69 | } 70 | } 71 | 72 | } // Qt3DRaytrace 73 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qmesh_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | 18 | class QMeshPrivate : public QGeometryRendererPrivate 19 | { 20 | public: 21 | Q_DECLARE_PUBLIC(QMesh) 22 | 23 | QUrl m_source; 24 | QMesh::Status m_status = QMesh::None; 25 | }; 26 | 27 | class MeshLoader final : public QGeometryFactory 28 | { 29 | public: 30 | explicit MeshLoader(const QMesh *mesh); 31 | 32 | QGeometry *create() override; 33 | 34 | private: 35 | QScopedPointer m_importer; 36 | QUrl m_source; 37 | }; 38 | 39 | } // Qt3DRaytrace 40 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qrendersettings_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | struct QRenderSettingsData 16 | { 17 | Qt3DCore::QNodeId cameraId; 18 | 19 | int primarySamples = 1; 20 | int secondarySamples = 1; 21 | int minDepth = 1; 22 | int maxDepth = 3; 23 | 24 | float directRadianceClamp = 0.0f; 25 | float indirectRadianceClamp = 0.0f; 26 | 27 | QColor skyColor = Qt::GlobalColor::black; 28 | float skyIntensity = 1.0f; 29 | Qt3DCore::QNodeId skyTextureId; 30 | QVector2D skyTextureOffset; 31 | }; 32 | 33 | class QRenderSettingsPrivate : public Qt3DCore::QComponentPrivate 34 | { 35 | public: 36 | Q_DECLARE_PUBLIC(QRenderSettings) 37 | QRenderSettingsData m_settings; 38 | QCamera *m_camera = nullptr; 39 | QAbstractTexture *m_skyTexture = nullptr; 40 | }; 41 | 42 | } // Qt3DRaytrace 43 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qtexture.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | // TODO: Implement status change. 15 | // TODO: Make texture image loader configurable. 16 | 17 | QTexture::QTexture(QNode *parent) 18 | : QAbstractTexture(*new QTexturePrivate, parent) 19 | {} 20 | 21 | QTexture::QTexture(QTexturePrivate &dd, QNode *parent) 22 | : QAbstractTexture(dd, parent) 23 | {} 24 | 25 | QUrl QTexture::source() const 26 | { 27 | Q_D(const QTexture); 28 | return d->m_source; 29 | } 30 | 31 | QTexture::Status QTexture::status() const 32 | { 33 | Q_D(const QTexture); 34 | return d->m_status; 35 | } 36 | 37 | void QTexture::setSource(const QUrl &source) 38 | { 39 | Q_D(QTexture); 40 | if(d->m_source != source) { 41 | d->m_source = source; 42 | setImageFactory(QTextureImageFactoryPtr(new TextureImageLoader(this))); 43 | emit sourceChanged(source); 44 | } 45 | } 46 | 47 | TextureImageLoader::TextureImageLoader(const QTexture *texture) 48 | : m_importer(new Raytrace::DefaultImageImporter) 49 | , m_source(texture->source()) 50 | {} 51 | 52 | QTextureImage *TextureImageLoader::create() 53 | { 54 | Q_ASSERT(m_importer); 55 | 56 | if(m_source.isEmpty()) { 57 | qCWarning(logImport) << "Texture image source path is empty"; 58 | return nullptr; 59 | } 60 | 61 | QImageData imageData; 62 | if(m_importer->import(m_source, imageData)) { 63 | QTextureImage *image = new QTextureImage; 64 | image->setData(imageData); 65 | return image; 66 | } 67 | else { 68 | return nullptr; 69 | } 70 | } 71 | 72 | } // Qt3DRaytrace 73 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qtexture_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | 18 | class QTexturePrivate : public QAbstractTexturePrivate 19 | { 20 | public: 21 | Q_DECLARE_PUBLIC(QTexture) 22 | 23 | QUrl m_source; 24 | QTexture::Status m_status = QTexture::None; 25 | }; 26 | 27 | class TextureImageLoader final : public QTextureImageFactory 28 | { 29 | public: 30 | explicit TextureImageLoader(const QTexture *texture); 31 | 32 | QTextureImage *create() override; 33 | 34 | private: 35 | QScopedPointer m_importer; 36 | QUrl m_source; 37 | }; 38 | 39 | } // Qt3DRaytrace 40 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qtextureimage.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | 9 | using namespace Qt3DCore; 10 | 11 | namespace Qt3DRaytrace { 12 | 13 | QTextureImage::QTextureImage(QNode *parent) 14 | : QNode(*new QTextureImagePrivate, parent) 15 | {} 16 | 17 | const QImageData &QTextureImage::data() const 18 | { 19 | Q_D(const QTextureImage); 20 | return d->m_data; 21 | } 22 | 23 | void QTextureImage::setData(const QImageData &imageData) 24 | { 25 | Q_D(QTextureImage); 26 | d->m_data = imageData; 27 | QNodePrivate::get(this)->notifyPropertyChange("data", QVariant::fromValue(d->m_data)); 28 | emit imageDataChanged(d->m_data); 29 | } 30 | 31 | void QTextureImage::clearData() 32 | { 33 | setData(QImageData()); 34 | } 35 | 36 | QTextureImage::QTextureImage(QTextureImagePrivate &dd, QNode *parent) 37 | : QNode(dd, parent) 38 | {} 39 | 40 | QNodeCreatedChangeBasePtr QTextureImage::createNodeCreationChange() const 41 | { 42 | Q_D(const QTextureImage); 43 | auto creationChange = QNodeCreatedChangePtr::create(this); 44 | creationChange->data = d->m_data; 45 | return creationChange; 46 | } 47 | 48 | } // Qt3DRaytrace 49 | -------------------------------------------------------------------------------- /src/raytrace/frontend/qtextureimage_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | 15 | class QTextureImagePrivate : public Qt3DCore::QNodePrivate 16 | { 17 | public: 18 | Q_DECLARE_PUBLIC(QTextureImage) 19 | QImageData m_data; 20 | }; 21 | 22 | } // Qt3DRaytrace 23 | -------------------------------------------------------------------------------- /src/raytrace/io/common_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace Qt3DRaytrace { 12 | namespace Raytrace { 13 | 14 | static inline QString getAssetPathFromUrl(const QUrl &url) 15 | { 16 | if(url.isLocalFile()) { 17 | return url.toLocalFile(); 18 | } 19 | else if(url.scheme() == QStringLiteral("qrc")) { 20 | return QStringLiteral(":") + url.path(); 21 | } 22 | else { 23 | return url.toString(); 24 | } 25 | } 26 | 27 | } // Raytrace 28 | } // Qt3DRaytrace 29 | -------------------------------------------------------------------------------- /src/raytrace/io/defaultimageimporter.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | // NOTE: Qt's own QImage lacks support for HDR formats, hence usage of stb_image. 13 | // TODO: Implement QImageReader for Radiance RGBE format, and possibly others. 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Raytrace { 18 | 19 | DefaultImageImporter::DefaultImageImporter() 20 | { 21 | stbi_set_flip_vertically_on_load(1); 22 | } 23 | 24 | bool DefaultImageImporter::import(const QUrl &url, QImageData &data) 25 | { 26 | QByteArray imageBytes; 27 | { 28 | QFile imageFile(getAssetPathFromUrl(url)); 29 | if(!imageFile.open(QFile::ReadOnly)) { 30 | qCCritical(logImport) << "Cannot open image file:" << url.toString(); 31 | return false; 32 | } 33 | 34 | qCInfo(logImport) << "Loading texture image:" << url.toString(); 35 | imageBytes = imageFile.readAll(); 36 | if(imageBytes.size() == 0) { 37 | qCCritical(logImport) << "Failed to read image file:" << url.toString(); 38 | return false; 39 | } 40 | } 41 | 42 | const stbi_uc *compressedData = reinterpret_cast(imageBytes.constData()); 43 | const int compressedDataSize = imageBytes.size(); 44 | 45 | int imageWidth, imageHeight, imageChannels; 46 | if(!stbi_info_from_memory(compressedData, compressedDataSize, &imageWidth, &imageHeight, &imageChannels)) { 47 | qCCritical(logImport) << "Failed to query image file properties:" << url.toString(); 48 | return false; 49 | } 50 | 51 | if(stbi_is_hdr_from_memory(compressedData, compressedDataSize) == 1) { 52 | float *image = stbi_loadf_from_memory(compressedData, compressedDataSize, &data.width, &data.height, &data.channels, 0); 53 | if(image) { 54 | const int imageSize = data.width * data.height * data.channels * sizeof(float); 55 | data.format = QImageData::Format::RGB; 56 | data.type = QImageData::ValueType::Float32; 57 | data.data = QByteArray(reinterpret_cast(image), imageSize); 58 | stbi_image_free(image); 59 | return true; 60 | } 61 | } 62 | else { 63 | // Expand RGB LDR images to RGBA. 64 | if(imageChannels == 3) { 65 | imageChannels = 4; 66 | } 67 | data.channels = imageChannels; 68 | 69 | int numActualChannels; 70 | stbi_uc *image = stbi_load_from_memory(compressedData, compressedDataSize, &data.width, &data.height, &numActualChannels, imageChannels); 71 | if(image) { 72 | const int imageSize = data.width * data.height * data.channels; 73 | data.format = QImageData::Format::RGBA; 74 | data.type = QImageData::ValueType::UInt8; 75 | data.data = QByteArray(reinterpret_cast(image), imageSize); 76 | stbi_image_free(image); 77 | return true; 78 | } 79 | } 80 | 81 | qCCritical(logImport) << "Failed to import texture image file:" << url.toString(); 82 | return false; 83 | } 84 | 85 | } // Raytrace 86 | } // Qt3DRaytrace 87 | -------------------------------------------------------------------------------- /src/raytrace/io/defaultimageimporter_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | class DefaultImageImporter final : public ImageImporter 16 | { 17 | public: 18 | DefaultImageImporter(); 19 | bool import(const QUrl &url, QImageData &data) override; 20 | }; 21 | 22 | } // Raytrace 23 | } // Qt3DRaytrace 24 | -------------------------------------------------------------------------------- /src/raytrace/io/defaultmeshimporter_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Raytrace { 14 | 15 | class DefaultMeshImporter final : public MeshImporter 16 | { 17 | public: 18 | bool import(const QUrl &url, QGeometryData &data) override; 19 | }; 20 | 21 | } // Raytrace 22 | } // Qt3DRaytrace 23 | -------------------------------------------------------------------------------- /src/raytrace/io/imageimporter_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | class ImageImporter 18 | { 19 | public: 20 | virtual ~ImageImporter() = default; 21 | virtual bool import(const QUrl &url, QImageData &data) = 0; 22 | }; 23 | 24 | } // Raytrace 25 | } // Qt3DRaytrace 26 | -------------------------------------------------------------------------------- /src/raytrace/io/meshimporter_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | class MeshImporter 18 | { 19 | public: 20 | virtual ~MeshImporter() = default; 21 | virtual bool import(const QUrl &url, QGeometryData &data) = 0; 22 | }; 23 | 24 | } // Raytrace 25 | } // Qt3DRaytrace 26 | -------------------------------------------------------------------------------- /src/raytrace/jobs/loadgeometryjob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace Qt3DCore; 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Raytrace { 15 | 16 | LoadGeometryJob::LoadGeometryJob(NodeManagers *managers, const HGeometryRenderer &handle) 17 | : m_nodeManagers(managers) 18 | , m_handle(handle) 19 | { 20 | Q_ASSERT(m_nodeManagers); 21 | } 22 | 23 | void LoadGeometryJob::run() 24 | { 25 | GeometryRenderer *geometryRenderer = m_nodeManagers->geometryRendererManager.data(m_handle); 26 | if(geometryRenderer) { 27 | geometryRenderer->loadGeometry(); 28 | } 29 | } 30 | 31 | } // Raytrace 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/jobs/loadgeometryjob_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | struct NodeManagers; 18 | 19 | class LoadGeometryJob final : public Qt3DCore::QAspectJob 20 | { 21 | public: 22 | LoadGeometryJob(NodeManagers *managers, const HGeometryRenderer &handle); 23 | 24 | void run() override; 25 | 26 | private: 27 | HGeometryRenderer m_handle; 28 | NodeManagers *m_nodeManagers; 29 | }; 30 | 31 | using LoadGeometryJobPtr = QSharedPointer; 32 | 33 | } // Raytrace 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /src/raytrace/jobs/loadtexturejob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace Qt3DCore; 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Raytrace { 15 | 16 | LoadTextureJob::LoadTextureJob(NodeManagers *managers, const HAbstractTexture &handle) 17 | : m_nodeManagers(managers) 18 | , m_handle(handle) 19 | { 20 | Q_ASSERT(m_nodeManagers); 21 | } 22 | 23 | void LoadTextureJob::run() 24 | { 25 | AbstractTexture *texture = m_nodeManagers->textureManager.data(m_handle); 26 | if(texture) { 27 | texture->loadImage(); 28 | } 29 | } 30 | 31 | } // Raytrace 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/jobs/loadtexturejob_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Raytrace { 16 | 17 | struct NodeManagers; 18 | 19 | class LoadTextureJob final : public Qt3DCore::QAspectJob 20 | { 21 | public: 22 | LoadTextureJob(NodeManagers *managers, const HAbstractTexture &handle); 23 | 24 | void run() override; 25 | 26 | private: 27 | HAbstractTexture m_handle; 28 | NodeManagers *m_nodeManagers; 29 | }; 30 | 31 | using LoadTextureJobPtr = QSharedPointer; 32 | 33 | } // Raytrace 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /src/raytrace/jobs/updateworldtransformjob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Qt3DRaytrace { 12 | namespace Raytrace { 13 | 14 | static void updateWorldTransform(Entity *entity, const Matrix4x4 &parentTransformMatrix) 15 | { 16 | Matrix4x4 worldTransformMatrix = parentTransformMatrix; 17 | const Transform *transform = entity->transformComponent(); 18 | if(transform) { 19 | worldTransformMatrix *= transform->transformMatrix(); 20 | } 21 | entity->worldTransformMatrix = worldTransformMatrix; 22 | 23 | for(Entity *childEntity : entity->children()) { 24 | updateWorldTransform(childEntity, worldTransformMatrix); 25 | } 26 | } 27 | 28 | void UpdateWorldTransformJob::run() 29 | { 30 | Q_ASSERT(m_rootEntity); 31 | 32 | Matrix4x4 parentTransformMatrix; 33 | Entity *parent = m_rootEntity->parent(); 34 | if(parent) { 35 | parentTransformMatrix = parent->worldTransformMatrix; 36 | } 37 | updateWorldTransform(m_rootEntity, parentTransformMatrix); 38 | } 39 | 40 | } // Raytrace 41 | } // Qt3DRaytrace 42 | -------------------------------------------------------------------------------- /src/raytrace/jobs/updateworldtransformjob_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace Qt3DRaytrace { 12 | namespace Raytrace { 13 | 14 | class Entity; 15 | 16 | class UpdateWorldTransformJob final : public Qt3DCore::QAspectJob 17 | { 18 | public: 19 | void setRoot(Entity *root) 20 | { 21 | m_rootEntity = root; 22 | } 23 | void run() override; 24 | 25 | private: 26 | Entity *m_rootEntity = nullptr; 27 | }; 28 | 29 | using UpdateWorldTransformJobPtr = QSharedPointer; 30 | 31 | } // Raytrace 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/qraytraceaspect_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | 16 | #include 17 | 18 | namespace Qt3DRaytrace { 19 | 20 | class QRaytraceAspectPrivate : public Qt3DCore::QAbstractAspectPrivate 21 | { 22 | public: 23 | void registerBackendTypes(); 24 | void updateServiceProviders(); 25 | 26 | QVector createGeometryRendererJobs() const; 27 | QVector createTextureJobs() const; 28 | 29 | QScopedPointer m_renderer; 30 | QScopedPointer m_nodeManagers; 31 | bool m_jobsSuspended = false; 32 | 33 | Q_DECLARE_PUBLIC(QRaytraceAspect) 34 | }; 35 | 36 | } // Qt3DRaytrace 37 | -------------------------------------------------------------------------------- /src/raytrace/qt3draytrace_global_p.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | Q_DECLARE_LOGGING_CATEGORY(logAspect) 14 | Q_DECLARE_LOGGING_CATEGORY(logImport) 15 | } // Qt3DRaytrace 16 | -------------------------------------------------------------------------------- /src/raytrace/qt3draytracecontext.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | namespace Qt3DRaytrace { 11 | namespace Quick { 12 | 13 | Qt3DRaytraceContext::Qt3DRaytraceContext(QObject *parent) 14 | : QObject(parent) 15 | {} 16 | 17 | QColor Qt3DRaytraceContext::lrgba(qreal r, qreal g, qreal b, qreal a) const 18 | { 19 | return Qt3DRaytrace::to_sRgb(QColor::fromRgbF(r, g, b, a)); 20 | } 21 | 22 | QColor Qt3DRaytraceContext::srgba(qreal r, qreal g, qreal b, qreal a) const 23 | { 24 | return QColor::fromRgbF(r, g, b, a); 25 | } 26 | 27 | } // Quick 28 | } // Qt3DRaytrace 29 | -------------------------------------------------------------------------------- /src/raytrace/renderers/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(vulkan) 2 | set(RENDERER_LIBRARIES ${VULKAN_LIBRARIES} PARENT_SCOPE) 3 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Sources 2 | target_sources(${MODULE_NAME} PRIVATE 3 | renderers/vulkan/vkcommon.h 4 | renderers/vulkan/vkresources.h 5 | renderers/vulkan/device.cpp 6 | renderers/vulkan/device.h 7 | renderers/vulkan/commandbuffer.cpp 8 | renderers/vulkan/commandbuffer.h 9 | renderers/vulkan/renderer.cpp 10 | renderers/vulkan/renderer.h 11 | renderers/vulkan/shadermodule.cpp 12 | renderers/vulkan/shadermodule.h 13 | renderers/vulkan/initializers.h 14 | renderers/vulkan/descriptors.h 15 | renderers/vulkan/resourcebarrier.h 16 | renderers/vulkan/geometry.h 17 | renderers/vulkan/glsl.h 18 | renderers/vulkan/services/frameadvanceservice.cpp 19 | renderers/vulkan/services/frameadvanceservice.h 20 | renderers/vulkan/pipeline/pipeline.cpp 21 | renderers/vulkan/pipeline/pipeline.h 22 | renderers/vulkan/pipeline/graphicspipeline.cpp 23 | renderers/vulkan/pipeline/graphicspipeline.h 24 | renderers/vulkan/pipeline/computepipeline.cpp 25 | renderers/vulkan/pipeline/computepipeline.h 26 | renderers/vulkan/pipeline/raytracingpipeline.cpp 27 | renderers/vulkan/pipeline/raytracingpipeline.h 28 | renderers/vulkan/jobs/buildgeometryjob.cpp 29 | renderers/vulkan/jobs/buildgeometryjob.h 30 | renderers/vulkan/jobs/buildscenetlasjob.cpp 31 | renderers/vulkan/jobs/buildscenetlasjob.h 32 | renderers/vulkan/jobs/updatematerialsjob.cpp 33 | renderers/vulkan/jobs/updatematerialsjob.h 34 | renderers/vulkan/jobs/updateemittersjob.cpp 35 | renderers/vulkan/jobs/updateemittersjob.h 36 | renderers/vulkan/jobs/updateinstancebufferjob.cpp 37 | renderers/vulkan/jobs/updateinstancebufferjob.h 38 | renderers/vulkan/jobs/updaterenderparametersjob.cpp 39 | renderers/vulkan/jobs/updaterenderparametersjob.h 40 | renderers/vulkan/jobs/uploadtexturejob.cpp 41 | renderers/vulkan/jobs/uploadtexturejob.h 42 | renderers/vulkan/jobs/destroyexpiredresourcesjob.cpp 43 | renderers/vulkan/jobs/destroyexpiredresourcesjob.h 44 | renderers/vulkan/managers/commandbuffermanager.cpp 45 | renderers/vulkan/managers/commandbuffermanager.h 46 | renderers/vulkan/managers/descriptormanager.cpp 47 | renderers/vulkan/managers/descriptormanager.h 48 | renderers/vulkan/managers/scenemanager.cpp 49 | renderers/vulkan/managers/scenemanager.h 50 | renderers/vulkan/managers/sceneresourceset.h 51 | renderers/vulkan/managers/cameramanager.cpp 52 | renderers/vulkan/managers/cameramanager.h 53 | ) 54 | 55 | # Shaders 56 | target_sources(${MODULE_NAME} PRIVATE 57 | renderers/vulkan/shaders/lib/bindings.glsl 58 | renderers/vulkan/shaders/lib/shared.glsl 59 | renderers/vulkan/shaders/vulkan_shaders.qrc 60 | ) 61 | 62 | set(VULKAN_LIBRARIES volk vma spirv_reflect PARENT_SCOPE) 63 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/descriptors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | enum class ResourceClass 16 | { 17 | AttributeBuffer, 18 | IndexBuffer, 19 | TextureImage, 20 | }; 21 | 22 | struct DescriptorHandle 23 | { 24 | uint32_t index = 0; 25 | ResourceClass rclass; 26 | 27 | operator bool() const 28 | { 29 | return index != 0; 30 | } 31 | }; 32 | 33 | struct DescriptorImageInfo : VkDescriptorImageInfo 34 | { 35 | explicit DescriptorImageInfo(VkSampler sampler_) 36 | { 37 | sampler = sampler_; 38 | imageView = VK_NULL_HANDLE; 39 | imageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 40 | } 41 | DescriptorImageInfo(VkImageView imageView_, ImageState imageState_) 42 | { 43 | sampler = VK_NULL_HANDLE; 44 | imageView = imageView_; 45 | imageLayout = ResourceBarrier::getImageLayoutFromState(imageState_); 46 | } 47 | DescriptorImageInfo(VkSampler sampler_, VkImageView imageView_, ImageState imageState_) 48 | { 49 | sampler = sampler_; 50 | imageView = imageView_; 51 | imageLayout = ResourceBarrier::getImageLayoutFromState(imageState_); 52 | } 53 | }; 54 | 55 | struct DescriptorBufferInfo : VkDescriptorBufferInfo 56 | { 57 | explicit DescriptorBufferInfo(VkBuffer buffer_, VkDeviceSize range_=VK_WHOLE_SIZE) 58 | { 59 | buffer = buffer_; 60 | offset = 0; 61 | range = range_; 62 | } 63 | DescriptorBufferInfo(VkBuffer buffer_, VkDeviceSize offset_, VkDeviceSize range_) 64 | { 65 | buffer = buffer_; 66 | offset = offset_; 67 | range = range_; 68 | } 69 | }; 70 | 71 | } // Vulkan 72 | } // Qt3DRaytrace 73 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/geometry.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | struct Geometry 16 | { 17 | Buffer attributes; 18 | Buffer indices; 19 | AccelerationStructure blas; 20 | uint64_t blasHandle = 0; 21 | uint32_t numVertices = 0; 22 | uint32_t numIndices = 0; 23 | }; 24 | 25 | struct GeometryInstance 26 | { 27 | float transform[12]; 28 | uint32_t instanceCustomIndex : 24; 29 | uint32_t mask : 8; 30 | uint32_t instanceOffset : 24; 31 | uint32_t flags : 8; 32 | uint64_t blasHandle; 33 | }; 34 | 35 | } // Vulkan 36 | } // Qt3DRaytrace 37 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/glsl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | 19 | namespace Qt3DRaytrace { 20 | namespace Vulkan { 21 | 22 | namespace glsl { 23 | 24 | template 25 | struct vec 26 | { 27 | T &operator[](int index) 28 | { 29 | Q_ASSERT(index >= 0 && index < N); 30 | return data[index]; 31 | } 32 | const T &operator[](int index) const 33 | { 34 | Q_ASSERT(index >= 0 && index < N); 35 | return data[index]; 36 | } 37 | T data[N]; 38 | }; 39 | 40 | } // glsl 41 | 42 | using uint = unsigned int; 43 | 44 | struct vec2 : glsl::vec 45 | { 46 | vec2() = default; 47 | vec2(const QVector2D &v) 48 | { 49 | data[0] = v.x(); 50 | data[1] = v.y(); 51 | } 52 | }; 53 | 54 | struct vec3 : glsl::vec 55 | { 56 | vec3() = default; 57 | vec3(const QVector3D &v) 58 | { 59 | data[0] = v.x(); 60 | data[1] = v.y(); 61 | data[2] = v.z(); 62 | } 63 | }; 64 | 65 | struct vec4 : glsl::vec 66 | { 67 | vec4() = default; 68 | vec4(const QVector4D &v) 69 | { 70 | data[0] = v.x(); 71 | data[1] = v.y(); 72 | data[2] = v.z(); 73 | data[3] = v.w(); 74 | } 75 | }; 76 | 77 | struct mat3x3 : glsl::vec 78 | { 79 | mat3x3() = default; 80 | mat3x3(const QMatrix3x3 &m) 81 | { 82 | const float *md = m.constData(); 83 | data[0] = md[0]; data[1] = md[1]; data[2] = md[2]; 84 | data[4] = md[3]; data[5] = md[4]; data[6] = md[5]; 85 | data[8] = md[6]; data[9] = md[7]; data[10] = md[8]; 86 | } 87 | }; 88 | using mat3 = mat3x3; 89 | 90 | struct mat4x4 : glsl::vec 91 | { 92 | mat4x4() = default; 93 | mat4x4(const QMatrix4x4 &m) 94 | { 95 | std::memcpy(data, m.constData(), sizeof(*this)); 96 | } 97 | }; 98 | using mat4 = mat4x4; 99 | 100 | struct mat3x4 : glsl::vec 101 | { 102 | mat3x4() = default; 103 | mat3x4(const QMatrix3x4 &m) 104 | { 105 | std::memcpy(data, m.constData(), sizeof(*this)); 106 | } 107 | }; 108 | 109 | #include 110 | #include 111 | 112 | } // Vulkan 113 | } // Qt3DRaytrace 114 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/buildgeometryjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Vulkan { 16 | 17 | class Renderer; 18 | 19 | class BuildGeometryJob final : public Qt3DCore::QAspectJob 20 | { 21 | public: 22 | BuildGeometryJob(Renderer *renderer, const Raytrace::HGeometry &handle); 23 | 24 | void run() override; 25 | 26 | private: 27 | Renderer *m_renderer; 28 | Raytrace::HGeometry m_handle; 29 | }; 30 | 31 | using BuildGeometryJobPtr = QSharedPointer; 32 | 33 | } // Vulkan 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/buildscenetlasjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Vulkan { 15 | 16 | class Renderer; 17 | 18 | class BuildSceneTopLevelAccelerationStructureJob final : public Qt3DCore::QAspectJob 19 | { 20 | public: 21 | BuildSceneTopLevelAccelerationStructureJob(Renderer *renderer); 22 | 23 | void run() override; 24 | 25 | private: 26 | QVector gatherGeometryInstances() const; 27 | 28 | Renderer *m_renderer; 29 | }; 30 | 31 | using BuildSceneTopLevelAccelerationStructureJobPtr = QSharedPointer; 32 | 33 | } // Vulkan 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/destroyexpiredresourcesjob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | DestroyExpiredResourcesJob::DestroyExpiredResourcesJob(Renderer *renderer) 16 | : m_renderer(renderer) 17 | { 18 | Q_ASSERT(m_renderer); 19 | } 20 | 21 | void DestroyExpiredResourcesJob::run() 22 | { 23 | auto *commandBufferManager = m_renderer->commandBufferManager(); 24 | if(commandBufferManager) { 25 | commandBufferManager->destroyExpiredResources(); 26 | } 27 | 28 | auto *sceneManager = m_renderer->sceneManager(); 29 | if(sceneManager) { 30 | sceneManager->destroyExpiredResources(); 31 | } 32 | } 33 | 34 | } // Vulkan 35 | } // Qt3DRaytrace 36 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/destroyexpiredresourcesjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | class Renderer; 16 | 17 | class DestroyExpiredResourcesJob final : public Qt3DCore::QAspectJob 18 | { 19 | public: 20 | explicit DestroyExpiredResourcesJob(Renderer *renderer); 21 | 22 | void run() override; 23 | 24 | private: 25 | Renderer *m_renderer; 26 | }; 27 | 28 | using DestroyExpiredResourcesJobPtr = QSharedPointer; 29 | 30 | } // Vulkan 31 | } // Qt3DRaytrace 32 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/updateemittersjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | 16 | namespace Raytrace { 17 | class TextureManager; 18 | } // Raytrace 19 | 20 | namespace Vulkan { 21 | 22 | class Renderer; 23 | 24 | class UpdateEmittersJob final : public Qt3DCore::QAspectJob 25 | { 26 | public: 27 | explicit UpdateEmittersJob(Renderer *renderer); 28 | 29 | void setTextureManager(Raytrace::TextureManager *textureManager); 30 | void run() override; 31 | 32 | private: 33 | Renderer *m_renderer; 34 | Raytrace::TextureManager *m_textureManager; 35 | }; 36 | 37 | using UpdateEmittersJobPtr = QSharedPointer; 38 | 39 | } // Vulkan 40 | } // Qt3DRaytrace 41 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/updateinstancebufferjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Vulkan { 15 | 16 | class Renderer; 17 | 18 | class UpdateInstanceBufferJob final : public Qt3DCore::QAspectJob 19 | { 20 | public: 21 | explicit UpdateInstanceBufferJob(Renderer *renderer); 22 | 23 | void run() override; 24 | 25 | private: 26 | Renderer *m_renderer; 27 | }; 28 | 29 | using UpdateInstanceBufferJobPtr = QSharedPointer; 30 | 31 | } // Vulkan 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/updatematerialsjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | 17 | namespace Raytrace { 18 | class TextureManager; 19 | } // Raytrace 20 | 21 | namespace Vulkan { 22 | 23 | class Renderer; 24 | 25 | class UpdateMaterialsJob final : public Qt3DCore::QAspectJob 26 | { 27 | public: 28 | UpdateMaterialsJob(Renderer *renderer, Raytrace::TextureManager *textureManager); 29 | 30 | void setDirtyMaterialHandles(QVector &materialHandles); 31 | void run() override; 32 | 33 | private: 34 | Renderer *m_renderer; 35 | Raytrace::TextureManager *m_textureManager; 36 | QVector m_dirtyMaterialHandles; 37 | }; 38 | 39 | using UpdateMaterialsJobPtr = QSharedPointer; 40 | 41 | } // Vulkan 42 | } // Qt3DRaytrace 43 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/updaterenderparametersjob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | using namespace Qt3DCore; 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | UpdateRenderParametersJob::UpdateRenderParametersJob(Renderer *renderer) 16 | : m_renderer(renderer) 17 | { 18 | Q_ASSERT(m_renderer); 19 | } 20 | 21 | void UpdateRenderParametersJob::run() 22 | { 23 | auto *cameraManager = m_renderer->cameraManager(); 24 | if(cameraManager) { 25 | cameraManager->updateParameters(); 26 | } 27 | } 28 | 29 | } // Vulkan 30 | } // Qt3DRaytrace 31 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/updaterenderparametersjob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Vulkan { 15 | 16 | class Renderer; 17 | 18 | class UpdateRenderParametersJob final : public Qt3DCore::QAspectJob 19 | { 20 | public: 21 | explicit UpdateRenderParametersJob(Renderer *renderer); 22 | 23 | void run() override; 24 | 25 | private: 26 | Renderer *m_renderer; 27 | }; 28 | 29 | using UpdateRenderParametersJobPtr = QSharedPointer; 30 | 31 | } // Vulkan 32 | } // Qt3DRaytrace 33 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/jobs/uploadtexturejob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace Qt3DRaytrace { 15 | namespace Vulkan { 16 | 17 | class Renderer; 18 | 19 | class UploadTextureJob final : public Qt3DCore::QAspectJob 20 | { 21 | public: 22 | UploadTextureJob(Renderer *renderer, const Raytrace::HTextureImage &handle); 23 | 24 | void run() override; 25 | 26 | private: 27 | Renderer *m_renderer; 28 | Raytrace::HTextureImage m_handle; 29 | }; 30 | 31 | using UploadTextureJobPtr = QSharedPointer; 32 | 33 | } // Vulkan 34 | } // Qt3DRaytrace 35 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/managers/cameramanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | 14 | namespace Raytrace { 15 | class Entity; 16 | } // Raytrace 17 | 18 | namespace Vulkan { 19 | 20 | struct RenderParameters; 21 | struct DisplayParameters; 22 | 23 | class CameraManager 24 | { 25 | public: 26 | CameraManager(); 27 | 28 | Raytrace::Entity *activeCamera() const; 29 | void setActiveCamera(Raytrace::Entity *activeCamera); 30 | 31 | void setDefaultParameters(); 32 | void updateParameters(); 33 | void applyRenderParameters(RenderParameters ¶ms) const; 34 | void applyDisplayPrameters(DisplayParameters ¶ms) const; 35 | 36 | private: 37 | Raytrace::Entity *m_activeCamera; 38 | 39 | QVector3D m_position; 40 | QVector3D m_upVector; 41 | QVector3D m_rightVector; 42 | QVector3D m_forwardVector; 43 | float m_aspectRatio; 44 | float m_tanHalfFOV; 45 | float m_lensRadius; 46 | float m_lensFocalDistance; 47 | float m_invGamma; 48 | float m_exposure; 49 | float m_tonemapFactor; 50 | }; 51 | 52 | } // Vulkan 53 | } // Qt3DRaytrace 54 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/managers/commandbuffermanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace Qt3DRaytrace { 18 | namespace Vulkan { 19 | 20 | class Renderer; 21 | class Device; 22 | 23 | struct TransientCommandBuffer 24 | { 25 | CommandBuffer buffer; 26 | CommandPool parentCommandPool; 27 | 28 | operator bool() const 29 | { 30 | return buffer != VK_NULL_HANDLE; 31 | } 32 | operator VkCommandBuffer() const 33 | { 34 | return buffer.handle; 35 | } 36 | operator CommandBuffer() const 37 | { 38 | return buffer; 39 | } 40 | const CommandBuffer *operator->() const 41 | { 42 | return &buffer; 43 | } 44 | }; 45 | 46 | class CommandBufferManager 47 | { 48 | public: 49 | explicit CommandBufferManager(Renderer *renderer); 50 | ~CommandBufferManager(); 51 | 52 | TransientCommandBuffer acquireCommandBuffer(); 53 | bool releaseCommandBuffer(TransientCommandBuffer &commandBuffer, const QVector &transientBuffers); 54 | bool releaseCommandBuffer(TransientCommandBuffer &commandBuffer, const QVector &transientImages); 55 | bool releaseCommandBuffer(TransientCommandBuffer &commandBuffer, const QVector &transientBuffers, const QVector &transientImages); 56 | 57 | bool executeCommandBufferImmediate(VkQueue queue, TransientCommandBuffer &commandBuffer); 58 | 59 | bool submitCommandBuffers(VkQueue queue); 60 | 61 | void destroyExpiredResources(); 62 | void proceedToNextFrame(); 63 | 64 | Q_DISABLE_COPY(CommandBufferManager) 65 | 66 | private: 67 | void cleanup(bool freeCommandBuffers=true); 68 | 69 | Device *m_device; 70 | 71 | struct ExecutableCommandBuffer { 72 | TransientCommandBuffer commandBuffer; 73 | QVector transientBuffers; 74 | QVector transientImages; 75 | }; 76 | struct PendingCommandBuffersBatch { 77 | QVector commandBuffers; 78 | QVector parentCommandPools; 79 | QVector transientBuffers; 80 | QVector transientImages; 81 | Fence commandsExecutedFence; 82 | }; 83 | 84 | QMutex m_commandBuffersMutex; 85 | QVector m_executableCommandBuffers; 86 | QVector m_pendingCommandBuffers; 87 | 88 | QVector m_commandPools; 89 | QThreadStorage m_localCommandPool; 90 | 91 | QMutex m_retiredResourcesMutex; 92 | QVector m_retiredBuffers; 93 | QVector m_retiredImages; 94 | }; 95 | 96 | } // Vulkan 97 | } // Qt3DRaytrace 98 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/managers/descriptormanager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace Qt3DRaytrace { 17 | namespace Vulkan { 18 | 19 | class Renderer; 20 | class Device; 21 | 22 | class DescriptorManager 23 | { 24 | public: 25 | explicit DescriptorManager(Renderer *renderer); 26 | ~DescriptorManager(); 27 | 28 | bool createDescriptorPool(ResourceClass rclass, uint32_t capacity); 29 | void destroyDescriptorPool(ResourceClass rclass); 30 | void destroyAllDescriptorPools(); 31 | 32 | DescriptorHandle allocateDescriptor(ResourceClass rclass); 33 | void updateBufferDescriptor(DescriptorHandle handle, const DescriptorBufferInfo &bufferInfo) const; 34 | void updateImageDescriptor(DescriptorHandle handle, const DescriptorImageInfo &imageInfo) const; 35 | 36 | VkDescriptorSet descriptorSet(ResourceClass rclass) const; 37 | uint32_t descriptorPoolCapacity(ResourceClass rclass) const; 38 | VkDescriptorBindingFlagsEXT descriptorBindingFlags(ResourceClass rclass) const; 39 | 40 | Q_DISABLE_COPY(DescriptorManager) 41 | 42 | private: 43 | Device *m_device; 44 | 45 | struct DescriptorPoolInfo { 46 | VkDescriptorPool pool; 47 | VkDescriptorSet set; 48 | VkDescriptorSetLayout layout; 49 | QAtomicInteger allocated; 50 | uint32_t capacity; 51 | }; 52 | QMap m_pools; 53 | }; 54 | 55 | } // Vulkan 56 | } // Qt3DRaytrace 57 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/managers/sceneresourceset.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | namespace Qt3DRaytrace { 14 | namespace Vulkan { 15 | 16 | template 17 | class SceneResourceSet 18 | { 19 | public: 20 | uint32_t addResource(Qt3DCore::QNodeId nodeId, const T &resource) 21 | { 22 | Q_ASSERT(!m_nodeToIndexMap.contains(nodeId)); 23 | uint32_t index = uint32_t(m_resources.size()); 24 | m_resources.append(resource); 25 | m_nodeToIndexMap.insert(nodeId, index); 26 | return index; 27 | } 28 | 29 | uint32_t addOrUpdateResource(Qt3DCore::QNodeId nodeId, const T &resource) 30 | { 31 | uint32_t index; 32 | auto it = m_nodeToIndexMap.find(nodeId); 33 | if(it == m_nodeToIndexMap.end()) { 34 | index = uint32_t(m_resources.size()); 35 | m_resources.append(resource); 36 | m_nodeToIndexMap.insert(nodeId, index); 37 | } 38 | else { 39 | index = *it; 40 | m_resources[int(index)] = resource; 41 | } 42 | return index; 43 | } 44 | 45 | uint32_t lookupIndex(Qt3DCore::QNodeId nodeId) const 46 | { 47 | return m_nodeToIndexMap.value(nodeId, ~0u); 48 | } 49 | 50 | uint32_t lookupResource(Qt3DCore::QNodeId nodeId, T &resource) const 51 | { 52 | uint32_t index = lookupIndex(nodeId); 53 | if(index != ~0u) { 54 | resource = m_resources[int(index)]; 55 | } 56 | return index; 57 | } 58 | 59 | const QVector &resources() const 60 | { 61 | return m_resources; 62 | } 63 | 64 | QVector takeResources() 65 | { 66 | QVector result(std::move(m_resources)); 67 | m_nodeToIndexMap.clear(); 68 | return result; 69 | } 70 | 71 | void clear() 72 | { 73 | m_resources.clear(); 74 | m_nodeToIndexMap.clear(); 75 | } 76 | 77 | private: 78 | QVector m_resources; 79 | QHash m_nodeToIndexMap; 80 | }; 81 | 82 | } // Vulkan 83 | } // Qt3DRaytrace 84 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/pipeline/computepipeline.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | namespace Qt3DRaytrace { 11 | namespace Vulkan { 12 | 13 | ComputePipelineBuilder::ComputePipelineBuilder(Device *device) 14 | : PipelineBuilderImpl(device) 15 | {} 16 | 17 | Pipeline ComputePipelineBuilder::build() const 18 | { 19 | Pipeline pipeline; 20 | pipeline.bindPoint = VK_PIPELINE_BIND_POINT_COMPUTE; 21 | 22 | if(!validate() || !buildBasePipeline(pipeline)) { 23 | return pipeline; 24 | } 25 | 26 | // TODO: Add support for specialization constants. 27 | VkPipelineShaderStageCreateInfo shaderStage = { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }; 28 | shaderStage.stage = VK_SHADER_STAGE_COMPUTE_BIT; 29 | shaderStage.module = m_shaders[0]->module(); 30 | shaderStage.pName = m_shaders[0]->entryPoint().data(); 31 | 32 | VkComputePipelineCreateInfo createInfo = { VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; 33 | createInfo.stage = shaderStage; 34 | createInfo.layout = pipeline.pipelineLayout; 35 | 36 | Result result; 37 | if(VKFAILED(result = vkCreateComputePipelines(*m_device, VK_NULL_HANDLE, 1, &createInfo, nullptr, &pipeline.handle))) { 38 | qCCritical(logVulkan) << "ComputePipelineBuilder: Failed to create compute pipeline" << result.toString(); 39 | m_device->destroyPipeline(pipeline); 40 | } 41 | return pipeline; 42 | } 43 | 44 | bool ComputePipelineBuilder::validate() const 45 | { 46 | if(m_shaders.empty()) { 47 | qCCritical(logVulkan) << "ComputePipelineBuilder: Pipeline validation failed: no shader modules present"; 48 | return false; 49 | } 50 | if(m_shaders.size() > 1 || m_shaders[0]->stage() != VK_SHADER_STAGE_COMPUTE_BIT) { 51 | qCCritical(logVulkan) << "ComputePipelineBuilder: Pipeline validation failed: compute pipelines require a single shader module of VK_SHADER_STAGE_COMPUTE_BIT"; 52 | return false; 53 | } 54 | return true; 55 | } 56 | 57 | } // Vulkan 58 | } // Qt3DRaytrace 59 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/pipeline/computepipeline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | class ComputePipelineBuilder final : public PipelineBuilderImpl 16 | { 17 | public: 18 | explicit ComputePipelineBuilder(Device *device); 19 | 20 | Pipeline build() const; 21 | bool validate() const; 22 | 23 | private: 24 | Q_DISABLE_COPY(ComputePipelineBuilder) 25 | }; 26 | 27 | } // Vulkan 28 | } // Qt3DRaytrace 29 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/pipeline/graphicspipeline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | class GraphicsPipelineBuilder final : public PipelineBuilderImpl 16 | { 17 | public: 18 | GraphicsPipelineBuilder(Device *device, VkRenderPass renderPass, uint32_t subpass=0); 19 | 20 | // TODO: Add pipeline configuration functions. 21 | 22 | Pipeline build() const; 23 | bool validate() const; 24 | 25 | private: 26 | struct VertexInputState { 27 | QVector bindingDescriptions; 28 | QVector attributeDescriptions; 29 | }; 30 | struct ViewportState { 31 | QVector viewport; 32 | QVector scissor; 33 | }; 34 | struct ColorBlendState { 35 | bool logicOpEnable; 36 | VkLogicOp logicOp; 37 | QVector attachments; 38 | float blendConstants[4]; 39 | }; 40 | 41 | VertexInputState m_vertexInputState; 42 | VkPipelineInputAssemblyStateCreateInfo m_inputAssemblyState; 43 | VkPipelineTessellationStateCreateInfo m_tessellationState; 44 | ViewportState m_viewportState; 45 | VkPipelineRasterizationStateCreateInfo m_rasterizationState; 46 | VkPipelineMultisampleStateCreateInfo m_multisampleState; 47 | VkPipelineDepthStencilStateCreateInfo m_depthStencilState; 48 | ColorBlendState m_colorBlendState = {}; 49 | QVector m_dynamicStates; 50 | VkRenderPass m_renderPass; 51 | uint32_t m_subpass; 52 | 53 | Q_DISABLE_COPY(GraphicsPipelineBuilder) 54 | }; 55 | 56 | } // Vulkan 57 | } // Qt3DRaytrace 58 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/pipeline/raytracingpipeline.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | namespace Qt3DRaytrace { 13 | namespace Vulkan { 14 | 15 | struct RayTracingPipeline : Pipeline 16 | { 17 | Buffer shaderBindingTable; 18 | VkDeviceSize shaderBindingTableStride = 0; 19 | VkDeviceSize shaderBindingTableHitGroupOffset = 0; 20 | }; 21 | 22 | class RayTracingPipelineBuilder final : public PipelineBuilderImpl 23 | { 24 | public: 25 | explicit RayTracingPipelineBuilder(Device *device); 26 | 27 | RayTracingPipelineBuilder &maxRecursionDepth(uint32_t maxDepth); 28 | 29 | RayTracingPipeline build() const; 30 | bool validate() const; 31 | 32 | private: 33 | bool buildShaderGroups(QVector &shaderGroups, uint32_t &firstHitGroupIndex) const; 34 | 35 | uint32_t m_maxRecursionDepth; 36 | 37 | Q_DISABLE_COPY(RayTracingPipelineBuilder) 38 | }; 39 | 40 | } // Vulkan 41 | } // Qt3DRaytrace 42 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/services/frameadvanceservice.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #include 8 | 9 | namespace Qt3DRaytrace { 10 | namespace Vulkan { 11 | 12 | FrameAdvanceService::FrameAdvanceService() 13 | : Qt3DCore::QAbstractFrameAdvanceService(QStringLiteral("Vulkan Frame Advance Service")) 14 | {} 15 | 16 | qint64 FrameAdvanceService::waitForNextFrame() 17 | { 18 | m_semaphore.acquire(); 19 | return m_elapsedTimer.nsecsElapsed(); 20 | } 21 | 22 | void FrameAdvanceService::start() 23 | { 24 | m_elapsedTimer.start(); 25 | } 26 | 27 | void FrameAdvanceService::stop() 28 | { 29 | proceedToNextFrame(); 30 | } 31 | 32 | void FrameAdvanceService::proceedToNextFrame() 33 | { 34 | m_semaphore.release(); 35 | } 36 | 37 | } // Vulkan 38 | } // Qt3DRaytrace 39 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/services/frameadvanceservice.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Vulkan { 17 | 18 | class FrameAdvanceService final : public Qt3DCore::QAbstractFrameAdvanceService 19 | { 20 | public: 21 | FrameAdvanceService(); 22 | 23 | qint64 waitForNextFrame() override; 24 | void start() override; 25 | void stop() override; 26 | 27 | void proceedToNextFrame(); 28 | 29 | private: 30 | QSemaphore m_semaphore; 31 | QElapsedTimer m_elapsedTimer; 32 | }; 33 | 34 | } // Vulkan 35 | } // Qt3DRaytrace 36 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shadermodule.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace Qt3DRaytrace { 16 | namespace Vulkan { 17 | 18 | class ShaderModule 19 | { 20 | public: 21 | struct DescriptorSetLayoutBinding { 22 | QString name; 23 | uint32_t binding; 24 | VkDescriptorType type; 25 | uint32_t count; 26 | }; 27 | struct DescriptorSetLayout { 28 | uint32_t set; 29 | QVector bindings; 30 | }; 31 | struct PushConstantRange { 32 | QString name; 33 | uint32_t offset; 34 | uint32_t size; 35 | }; 36 | 37 | ShaderModule() = default; 38 | ShaderModule(VkDevice device, const QString &name, const QString &entryPoint="main"); 39 | ShaderModule(VkDevice device, const QByteArray &bytecode, const QString &entryPoint="main"); 40 | ~ShaderModule(); 41 | 42 | bool loadFromFile(VkDevice device, const QString &filename, const QString &entryPoint="main"); 43 | bool loadFromBytecode(VkDevice device, const QByteArray &bytecode, const QString &entryPoint="main"); 44 | void destroy(); 45 | 46 | bool isValid() const 47 | { 48 | return m_device != VK_NULL_HANDLE && m_module != VK_NULL_HANDLE; 49 | } 50 | 51 | VkShaderModule module() const { return m_module; } 52 | VkShaderStageFlagBits stage() const { return m_stage; } 53 | const QByteArray &entryPoint() const { return m_entryPoint; } 54 | 55 | const QVector &descriptorSets() const { return m_descriptorSets; } 56 | const QVector &pushConstants() const { return m_pushConstants; } 57 | 58 | static QString getModulePath(const QString &name); 59 | 60 | private: 61 | VkDevice m_device = VK_NULL_HANDLE; 62 | VkShaderModule m_module = VK_NULL_HANDLE; 63 | VkShaderStageFlagBits m_stage; 64 | QByteArray m_entryPoint; 65 | QVector m_descriptorSets; 66 | QVector m_pushConstants; 67 | }; 68 | 69 | } // Vulkan 70 | } // Qt3DRaytrace 71 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/.gitignore: -------------------------------------------------------------------------------- 1 | *.spv 2 | *.qrc 3 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/compile.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | # Copyright (C) 2018-2019 Michał Siejak 4 | # This file is part of Quartz - a raytracing aspect for Qt3D. 5 | # See LICENSE file for licensing information 6 | 7 | # Compiles GLSL shaders to SPIR-V and generates appropriate QRC file. 8 | 9 | import os, sys, shutil 10 | import glob 11 | import subprocess 12 | 13 | def find_glslang(): 14 | GLSLANG_NAME = "glslangValidator" 15 | GLSLANG_FALLBACK_PATH = "/opt/glslang/bin" 16 | 17 | # Try standard PATH. 18 | glslang = shutil.which(GLSLANG_NAME) 19 | 20 | # Try VULKAN_SDK bin directory. 21 | if glslang is None: 22 | vulkan_sdk = os.environ.get("VULKAN_SDK") 23 | if vulkan_sdk is not None: 24 | vulkan_sdk_bin = os.path.join(vulkan_sdk, "bin") 25 | glslang = shutil.which(GLSLANG_NAME, path=vulkan_sdk_bin) 26 | 27 | # Try fallback path on POSIX systems. 28 | if glslang is None and os.name == "posix": 29 | glslang = shutil.which(GLSLANG_NAME, path=GLSLANG_FALLBACK_PATH) 30 | 31 | return glslang 32 | 33 | def write_qrc_file(filename, shader_names): 34 | with open(filename, 'w') as f: 35 | print("\n\n", file=f) 36 | for shader_name in shader_names: 37 | print(" spv/{0}.spv".format(shader_name), file=f) 38 | print("\n", file=f) 39 | 40 | def compile_shaders(base_path, glslang): 41 | output_path = os.path.join(base_path, "spv") 42 | qrc_file_path = os.path.join(base_path, "vulkan_shaders.qrc") 43 | 44 | try: 45 | os.mkdir(output_path) 46 | except FileExistsError: 47 | pass 48 | 49 | shader_names = [] 50 | for glsl_path in glob.glob(os.path.join(base_path, "*.glsl")): 51 | shader_name = os.path.splitext(os.path.basename(glsl_path))[0] 52 | spv_path = os.path.join(output_path, "{0}.spv".format(shader_name)) 53 | subprocess.run([glslang, "-V", glsl_path, "-o", spv_path]) 54 | shader_names.append(shader_name) 55 | 56 | write_qrc_file(qrc_file_path, shader_names) 57 | 58 | def main(): 59 | glslang = find_glslang() 60 | if glslang is None: 61 | print("Error: Unable to find glslangValidator. Make sure it's either in PATH or that VULKAN_SDK is defined and points to the right directory.", file=sys.stderr) 62 | sys.exit(1) 63 | 64 | print("Using GLSL compiler: {0}".format(glslang)) 65 | base_path = os.path.dirname(os.path.realpath(__file__)) 66 | compile_shaders(base_path, glslang) 67 | 68 | if __name__ == "__main__": 69 | main() 70 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/display.frag.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_GOOGLE_include_directive : require 9 | 10 | #include "lib/common.glsl" 11 | 12 | layout(location=0) in vec2 uv; 13 | layout(location=0) out vec4 outColor; 14 | 15 | layout(set=DS_Display, binding=Binding_DisplayBuffer) uniform sampler2D displayBuffer; 16 | 17 | layout(push_constant) uniform DisplayParametersBlock 18 | { 19 | DisplayParameters displayParams; 20 | }; 21 | 22 | void main() 23 | { 24 | vec3 linearColor = texture(displayBuffer, uv).rgb * displayParams.exposure; 25 | 26 | // Reinhard tonemapping operator. 27 | // see: "Photographic Tone Reproduction for Digital Images", eq. 4 28 | float luminance = dot(linearColor, vec3(0.2126, 0.7152, 0.0722)); 29 | float mappedLuminance = (luminance * (1.0 + luminance / displayParams.tonemapFactorSq)) / (1.0 + luminance); 30 | 31 | // Scale color by ratio of average luminances. 32 | vec3 mappedColor = (mappedLuminance / luminance) * linearColor; 33 | 34 | // Gamma correction. 35 | outColor = vec4(pow(mappedColor, vec3(displayParams.invGamma)), 1.0); 36 | } 37 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/display.vert.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | layout(location=0) out vec2 uv; 9 | 10 | void main() 11 | { 12 | if(gl_VertexIndex == 0) { 13 | uv = vec2(1.0, 1.0); 14 | gl_Position = vec4(1.0, 1.0, 0.0, 1.0); 15 | } 16 | else if(gl_VertexIndex == 1) { 17 | uv = vec2(1.0, -1.0); 18 | gl_Position = vec4(1.0, -3.0, 0.0, 1.0); 19 | } 20 | else /* if(gl_VertexIndex == 2) */ { 21 | uv = vec2(-1.0, 1.0); 22 | gl_Position = vec4(-3.0, 1.0, 0.0, 1.0); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/bindings.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_BINDINGS_H 8 | #define QUARTZ_SHADERS_BINDINGS_H 9 | 10 | const uint DS_Display = 0; 11 | 12 | const uint Binding_DisplayBuffer = 0; 13 | 14 | const uint DS_Render = 0; 15 | const uint DS_AttributeBuffer = 1; 16 | const uint DS_IndexBuffer = 2; 17 | const uint DS_TextureImage = 3; 18 | 19 | const uint Binding_TLAS = 0; 20 | const uint Binding_Instances = 1; 21 | const uint Binding_Materials = 2; 22 | const uint Binding_Emitters = 3; 23 | const uint Binding_RenderBuffer = 4; 24 | const uint Binding_PrevRenderBuffer = 5; 25 | const uint Binding_TextureSampler = 6; 26 | 27 | const uint Shader_PathTraceHit = 0; 28 | const uint Shader_PathTraceMiss = 0; 29 | const uint Shader_QueryEmissionHit = 1; 30 | const uint Shader_QueryEmissionMiss = 1; 31 | const uint Shader_QueryVisibilityHit = 2; 32 | const uint Shader_QueryVisibilityMiss = 2; 33 | 34 | #endif // QUARTZ_SHADERS_BINDINGS_H 35 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/common.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_COMMON_H 8 | #define QUARTZ_SHADERS_COMMON_H 9 | 10 | #include "bindings.glsl" 11 | #include "shared.glsl" 12 | 13 | const float PI = 3.141592; 14 | const float HalfPI = 0.5 * PI; 15 | const float TwoPI = 2.0 * PI; 16 | const float InvPI = 1.0 / PI; 17 | const float InvTwoPI = 1.0 / TwoPI; 18 | 19 | const float Epsilon = 0.0001; 20 | const float Infinity = 1000000.0; 21 | 22 | const float MinRoughness = 0.02; 23 | const float MinTerminationThreshold = 0.05; 24 | 25 | #include "sampling.glsl" 26 | 27 | struct PathTracePayload { 28 | vec3 L; // Radiance 29 | vec3 T; // Path throughput 30 | RNG rng; 31 | uint depth; 32 | }; 33 | 34 | struct Triangle { 35 | Attributes v1; 36 | Attributes v2; 37 | Attributes v3; 38 | }; 39 | 40 | struct TangentBasis { 41 | vec3 T, N, B; 42 | }; 43 | 44 | struct DifferentialSurface { 45 | TangentBasis basis; 46 | vec3 albedo; 47 | vec3 reflectance; 48 | float roughness; 49 | float metalness; 50 | float alpha, alpha2; 51 | float swSpecular; 52 | }; 53 | 54 | float maxcomp(vec3 v) 55 | { 56 | return max(max(v.x, v.y), v.z); 57 | } 58 | 59 | bool isblack(vec3 v) 60 | { 61 | return dot(v, v) < Epsilon; 62 | } 63 | 64 | float luminance(vec3 color) 65 | { 66 | return dot(color, vec3(0.2126, 0.7152, 0.0722)); 67 | } 68 | 69 | float pow2(float x) 70 | { 71 | return x * x; 72 | } 73 | 74 | float pow5(float x) 75 | { 76 | return (x * x) * (x * x) * x; 77 | } 78 | 79 | vec2 spherical(vec3 w) 80 | { 81 | return vec2( 82 | atan(w.z, w.x) * InvTwoPI, 83 | acos(w.y) * InvPI 84 | ); 85 | } 86 | 87 | vec2 skyuv(vec3 w) 88 | { 89 | vec2 s = spherical(w); 90 | return vec2(s.x, 1.0 - s.y); 91 | } 92 | 93 | #endif // QUARTZ_SHADERS_COMMON_H 94 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/geometry.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_RAYHIT_H 8 | #define QUARTZ_SHADERS_RAYHIT_H 9 | 10 | #include "common.glsl" 11 | 12 | vec2 blerp(vec2 b, vec2 p1, vec2 p2, vec2 p3) 13 | { 14 | return (1.0 - b.x - b.y) * p1 + b.x * p2 + b.y * p3; 15 | } 16 | 17 | vec3 blerp(vec2 b, vec3 p1, vec3 p2, vec3 p3) 18 | { 19 | return (1.0 - b.x - b.y) * p1 + b.x * p2 + b.y * p3; 20 | } 21 | 22 | vec3 getPosition(Triangle triangle, vec2 b) 23 | { 24 | return blerp(b, triangle.v1.position, triangle.v2.position, triangle.v3.position); 25 | } 26 | 27 | vec3 getPositionWorld(Triangle triangle, mat4x4 objectToWorld, vec2 b) 28 | { 29 | return vec3(objectToWorld * vec4(getPosition(triangle, b), 1.0)); 30 | } 31 | 32 | vec3 getNormal(Triangle triangle, vec2 b) 33 | { 34 | return blerp(b, triangle.v1.normal, triangle.v2.normal, triangle.v3.normal); 35 | } 36 | 37 | vec3 getNormalWorld(Triangle triangle, mat3x3 basisObjectToWorld, vec2 b) 38 | { 39 | return normalize(basisObjectToWorld * getNormal(triangle, b)); 40 | } 41 | 42 | vec3 getTangent(Triangle triangle, vec2 b) 43 | { 44 | return blerp(b, triangle.v1.tangent, triangle.v2.tangent, triangle.v3.tangent); 45 | } 46 | 47 | vec3 getTangentWorld(Triangle triangle, mat3x3 basisObjectToWorld, vec2 b) 48 | { 49 | return normalize(basisObjectToWorld * getTangent(triangle, b)); 50 | } 51 | 52 | vec2 getTexCoord(Triangle triangle, vec2 b) 53 | { 54 | return blerp(b, triangle.v1.texcoord, triangle.v2.texcoord, triangle.v3.texcoord); 55 | } 56 | 57 | TangentBasis getTangentBasis(Triangle triangle, mat3x3 basisObjectToWorld, vec2 b) 58 | { 59 | TangentBasis basis; 60 | basis.N = getNormalWorld(triangle, basisObjectToWorld, b); 61 | basis.T = getTangentWorld(triangle, basisObjectToWorld, b); 62 | basis.B = cross(basis.N, basis.T); 63 | return basis; 64 | } 65 | 66 | vec3 tangentToWorld(TangentBasis basis, vec3 v) 67 | { 68 | return basis.T * v.x + basis.B * v.y + basis.N * v.z; 69 | } 70 | 71 | vec3 worldToTangent(TangentBasis basis, vec3 v) 72 | { 73 | return vec3(dot(basis.T, v), dot(basis.B, v), dot(basis.N, v)); 74 | } 75 | 76 | float cosThetaWorld(vec3 v, vec3 N) 77 | { 78 | return max(dot(v, N), 0.0); 79 | } 80 | 81 | float cosThetaTangent(vec3 v) 82 | { 83 | return max(v.z, 0.0); 84 | } 85 | 86 | #endif // QUARTZ_SHADERS_RAYHIT_H -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/sampling.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_SAMPLING_H 8 | #define QUARTZ_SHADERS_SAMPLING_H 9 | 10 | #include "xoroshiro64s.glsl" 11 | 12 | float nextFloat(inout RNG rng) 13 | { 14 | uint u = 0x3f800000 | (rngNext(rng) >> 9); 15 | return uintBitsToFloat(u) - 1.0; 16 | } 17 | 18 | uint nextUInt(inout RNG rng, uint nmax) 19 | { 20 | float f = nextFloat(rng); 21 | return uint(floor(f * nmax)); 22 | } 23 | 24 | vec2 nextVec2(inout RNG rng) 25 | { 26 | return vec2(nextFloat(rng), nextFloat(rng)); 27 | } 28 | 29 | vec3 nextVec3(inout RNG rng) 30 | { 31 | return vec3(nextFloat(rng), nextFloat(rng), nextFloat(rng)); 32 | } 33 | 34 | vec2 nextStratified(inout RNG rng, vec2 p, float delta) 35 | { 36 | return vec2( 37 | p.x + nextFloat(rng) * delta, 38 | p.y + nextFloat(rng) * delta 39 | ); 40 | } 41 | 42 | vec2 sampleRectangle(vec2 u, vec2 rmin, vec2 rmax) 43 | { 44 | return rmin + u * (rmax - rmin); 45 | } 46 | 47 | vec2 sampleDisk(vec2 u) 48 | { 49 | float r = sqrt(u.x); 50 | float theta = TwoPI * u.y; 51 | return r * vec2(cos(theta), sin(theta)); 52 | } 53 | 54 | vec2 sampleDiskConcentric(vec2 u) 55 | { 56 | vec2 up = 2.0 * u - vec2(1.0); 57 | if(up == vec2(0.0)) { 58 | return vec2(0.0); 59 | } 60 | else { 61 | float r, theta; 62 | if(abs(up.x) > abs(up.y)) { 63 | r = up.x; 64 | theta = 0.25 * PI * (up.y / up.x); 65 | } 66 | else { 67 | r = up.y; 68 | theta = 0.5 * PI - 0.25 * PI * (up.x / up.y); 69 | } 70 | return r * vec2(cos(theta), sin(theta)); 71 | } 72 | } 73 | 74 | float pdfDisk() 75 | { 76 | return InvPI; 77 | } 78 | 79 | vec3 sampleHemisphere(vec2 u) 80 | { 81 | float phi = TwoPI * u.y; 82 | float sinTheta = sqrt(1.0 - u.x*u.x); 83 | return vec3( 84 | cos(phi) * sinTheta, 85 | sin(phi) * sinTheta, 86 | u.x 87 | ); 88 | } 89 | 90 | float pdfHemisphere() 91 | { 92 | return 0.5 * InvPI; 93 | } 94 | 95 | vec3 sampleHemisphereCosine(vec2 u) 96 | { 97 | vec2 d = sampleDisk(u); 98 | return vec3(d.x, d.y, sqrt(1.0 - d.x*d.x - d.y*d.y)); 99 | } 100 | 101 | vec3 sampleHemisphereCosineConcentric(vec2 u) 102 | { 103 | vec2 d = sampleDiskConcentric(u); 104 | return vec3(d.x, d.y, sqrt(1.0 - d.x*d.x - d.y*d.y)); 105 | } 106 | 107 | float pdfHemisphereCosine(float cosTheta) 108 | { 109 | return cosTheta * InvPI; 110 | } 111 | 112 | vec2 sampleTriangle(vec2 u) 113 | { 114 | float uxsqrt = sqrt(u.x); 115 | return vec2(1.0 - uxsqrt, u.y * uxsqrt); 116 | } 117 | 118 | float pdfTriangle(float area) 119 | { 120 | return 1.0 / area; 121 | } 122 | 123 | #endif // QUARTZ_SHADERS_SAMPLING_H -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/shared.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_TYPES_H 8 | #define QUARTZ_SHADERS_TYPES_H 9 | 10 | struct Material 11 | { 12 | vec4 albedo; // +roughness 13 | vec4 emission; // +metalness 14 | uint albedoTexture; 15 | uint roughnessTexture; 16 | uint metalnessTexture; 17 | float _padding[1]; 18 | }; 19 | 20 | struct Emitter 21 | { 22 | uint instanceIndex; 23 | uint geometryIndex; 24 | uint textureIndex; 25 | float intensity; 26 | vec3 radiance; 27 | vec3 direction; 28 | }; 29 | 30 | struct Attributes 31 | { 32 | vec3 position; 33 | vec3 normal; 34 | vec3 tangent; 35 | vec2 texcoord; 36 | float _padding[2]; 37 | }; 38 | 39 | struct Face 40 | { 41 | uint vertices[3]; 42 | }; 43 | 44 | // TODO: Switch to mat3x4 for transform to save space. 45 | struct EntityInstance 46 | { 47 | uint materialIndex; 48 | uint geometryIndex; 49 | uint geometryNumFaces; 50 | float _padding[1]; 51 | mat4x4 transform; 52 | mat3x3 basisTransform; 53 | }; 54 | 55 | struct RenderParameters 56 | { 57 | uint minDepth; 58 | uint maxDepth; 59 | uint frameNumber; 60 | uint numEmitters; 61 | uint numPrimarySamples; 62 | uint numSecondarySamples; 63 | float directRadianceClamp; 64 | float indirectRadianceClamp; 65 | vec4 cameraPositionAspect; 66 | vec4 cameraUpVectorTanHalfFOV; 67 | vec4 cameraRightVectorLensR; 68 | vec4 cameraForwardVectorLensF; 69 | }; 70 | 71 | struct DisplayParameters 72 | { 73 | float invGamma; 74 | float exposure; 75 | float tonemapFactorSq; 76 | float _padding[1]; 77 | }; 78 | 79 | #endif // QUARTZ_SHADERS_TYPES_H 80 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/lib/xoroshiro64s.glsl: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #ifndef QUARTZ_SHADERS_XOROSHIRO64S_H 8 | #define QUARTZ_SHADERS_XOROSHIRO64S_H 9 | 10 | struct RNG 11 | { 12 | uvec2 s; 13 | }; 14 | 15 | uint rotl(uint x, uint k) 16 | { 17 | return (x << k) | (x >> (32 - k)); 18 | } 19 | 20 | // Xoroshiro64* RNG 21 | uint rngNext(inout RNG rng) 22 | { 23 | uint result = rng.s.x * 0x9e3779bb; 24 | 25 | rng.s.y ^= rng.s.x; 26 | rng.s.x = rotl(rng.s.x, 26) ^ rng.s.y ^ (rng.s.y << 9); 27 | rng.s.y = rotl(rng.s.y, 13); 28 | 29 | return result; 30 | } 31 | 32 | // Thomas Wang 32-bit hash. 33 | uint rngHash(uint seed) 34 | { 35 | seed = (seed ^ 61) ^ (seed >> 16); 36 | seed *= 9; 37 | seed = seed ^ (seed >> 4); 38 | seed *= 0x27d4eb2d; 39 | seed = seed ^ (seed >> 15); 40 | return seed; 41 | } 42 | 43 | RNG rngInit(uvec2 id, uint frameIndex) 44 | { 45 | uint s0 = (id.x << 16) | id.y; 46 | uint s1 = frameIndex; 47 | 48 | RNG rng; 49 | rng.s.x = rngHash(s0); 50 | rng.s.y = rngHash(s1); 51 | rngNext(rng); 52 | return rng; 53 | } 54 | 55 | #endif // QUARTZ_SHADERS_XOROSHIRO64S_H -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/pathtrace.rgen.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_GOOGLE_include_directive : require 9 | #extension GL_NV_ray_tracing : require 10 | 11 | #include "lib/common.glsl" 12 | #include "lib/sampling.glsl" 13 | 14 | layout(push_constant) uniform RenderParametersBlock 15 | { 16 | RenderParameters params; 17 | }; 18 | 19 | layout(set=DS_Render, binding=Binding_TLAS) uniform accelerationStructureNV scene; 20 | layout(set=DS_Render, binding=Binding_RenderBuffer, rgba16f) restrict writeonly uniform image2D renderBuffer; 21 | layout(set=DS_Render, binding=Binding_PrevRenderBuffer, rgba16f) restrict readonly uniform image2D prevRenderBuffer; 22 | 23 | layout(location=0) rayPayloadNV PathTracePayload pPathTrace; 24 | 25 | vec3 cameraToWorld(vec3 v, vec3 right, vec3 up, vec3 forward) 26 | { 27 | return right * v.x + up * v.y + forward * v.z; 28 | } 29 | 30 | void generateCameraRay(vec2 pixelUV, vec2 lensUV, out vec3 p, out vec3 wo) 31 | { 32 | const vec3 up = params.cameraUpVectorTanHalfFOV.xyz; 33 | const vec3 right = params.cameraRightVectorLensR.xyz; 34 | const vec3 forward = params.cameraForwardVectorLensF.xyz; 35 | 36 | const float aspect = params.cameraPositionAspect.w; 37 | const float tanHalfFOV = params.cameraUpVectorTanHalfFOV.w; 38 | const float lensRadius = params.cameraRightVectorLensR.w; 39 | const float lensFocalDistance = params.cameraForwardVectorLensF.w; 40 | 41 | float tx = (2.0 * pixelUV.x - 1.0) * tanHalfFOV * aspect; 42 | float ty = (2.0 * pixelUV.y - 1.0) * tanHalfFOV; 43 | 44 | vec3 pCamera = vec3(0.0); 45 | vec3 woCamera = normalize(vec3(tx, ty, 1.0)); 46 | if(lensRadius > 0.0) { 47 | float tFocus = lensFocalDistance / woCamera.z; 48 | vec3 pFocus = tFocus * woCamera; 49 | pCamera.xy = lensRadius * sampleDiskConcentric(lensUV); 50 | woCamera = normalize(pFocus - pCamera); 51 | } 52 | p = cameraToWorld(pCamera, right, up, forward) + params.cameraPositionAspect.xyz; 53 | wo = cameraToWorld(woCamera, right, up, forward); 54 | } 55 | 56 | void main() 57 | { 58 | vec2 pixelSize = vec2(1.0) / vec2(gl_LaunchSizeNV.xy); 59 | vec2 pixelLocation = vec2(gl_LaunchIDNV.xy) * pixelSize; 60 | 61 | vec3 prevColor = imageLoad(prevRenderBuffer, ivec2(gl_LaunchIDNV)).rgb; 62 | 63 | pPathTrace.rng = rngInit(gl_LaunchIDNV.xy, params.frameNumber); 64 | pPathTrace.depth = 0; 65 | pPathTrace.T = vec3(1.0); 66 | 67 | vec2 jitter = pixelSize * (nextVec2(pPathTrace.rng) - 0.5); 68 | vec2 lensUV = nextVec2(pPathTrace.rng); 69 | vec2 pixelUV = pixelLocation + jitter; 70 | 71 | vec3 p, wo; 72 | generateCameraRay(pixelUV, lensUV, p, wo); 73 | traceNV(scene, gl_RayFlagsNoneNV, 0xFF, Shader_PathTraceHit, 1, Shader_PathTraceMiss, p, 0.0, wo, Infinity, 0); 74 | 75 | vec3 currentColor = prevColor + (pPathTrace.L - prevColor) / float(params.frameNumber); 76 | imageStore(renderBuffer, ivec2(gl_LaunchIDNV), vec4(currentColor, 1.0)); 77 | } 78 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/pathtrace.rmiss.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_NV_ray_tracing : require 9 | #extension GL_EXT_nonuniform_qualifier : require 10 | #extension GL_GOOGLE_include_directive : require 11 | 12 | #include "lib/common.glsl" 13 | #include "lib/resources.glsl" 14 | 15 | rayPayloadInNV PathTracePayload payload; 16 | 17 | void main() 18 | { 19 | if(payload.depth == 0) { 20 | payload.L = fetchSkyRadiance(skyuv(gl_WorldRayDirectionNV)); 21 | } 22 | else { 23 | payload.L = vec3(0.0); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/queryemission.rchit.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_GOOGLE_include_directive : require 9 | #extension GL_EXT_nonuniform_qualifier : require 10 | #extension GL_NV_ray_tracing : require 11 | 12 | #include "lib/common.glsl" 13 | #include "lib/resources.glsl" 14 | 15 | rayPayloadInNV vec3 pEmission; 16 | 17 | void main() 18 | { 19 | Material material = fetchMaterial(gl_InstanceID); 20 | pEmission = material.emission.rgb; 21 | } 22 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/queryemission.rmiss.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_NV_ray_tracing : require 9 | #extension GL_EXT_nonuniform_qualifier : require 10 | #extension GL_GOOGLE_include_directive : require 11 | 12 | #include "lib/common.glsl" 13 | #include "lib/resources.glsl" 14 | 15 | rayPayloadInNV vec3 pEmission; 16 | 17 | void main() 18 | { 19 | // Emitter #0 is always sky. 20 | pEmission = fetchSkyRadiance(skyuv(gl_WorldRayDirectionNV)); 21 | } 22 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/queryvisibility.rchit.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_NV_ray_tracing : require 9 | 10 | rayPayloadInNV float pVisibility; 11 | 12 | void main() 13 | { 14 | pVisibility = 0.0; 15 | } 16 | -------------------------------------------------------------------------------- /src/raytrace/renderers/vulkan/shaders/queryvisibility.rmiss.glsl: -------------------------------------------------------------------------------- 1 | #version 460 2 | /* 3 | * Copyright (C) 2018-2019 Michał Siejak 4 | * This file is part of Quartz - a raytracing aspect for Qt3D. 5 | * See LICENSE file for licensing information. 6 | */ 7 | 8 | #extension GL_NV_ray_tracing : require 9 | 10 | rayPayloadInNV float pVisibility; 11 | 12 | void main() 13 | { 14 | pVisibility = 1.0; 15 | } 16 | -------------------------------------------------------------------------------- /src/raytrace/utility/movingaverage.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2018-2019 Michał Siejak 3 | * This file is part of Quartz - a raytracing aspect for Qt3D. 4 | * See LICENSE file for licensing information. 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | 11 | namespace Qt3DRaytrace { 12 | namespace Utility { 13 | 14 | template 15 | class MovingAverage 16 | { 17 | public: 18 | explicit MovingAverage(int limit=100) 19 | : m_limit(limit) 20 | { 21 | Q_ASSERT(limit > 0); 22 | m_values.reserve(limit); 23 | } 24 | 25 | T add(T value) 26 | { 27 | if(m_values.size() == m_limit) { 28 | m_average = m_average + (value / m_limit) - (m_values.dequeue() / m_limit); 29 | m_values.enqueue(value); 30 | } 31 | else { 32 | m_values.enqueue(value); 33 | m_average += (value - m_average) / m_values.size(); 34 | } 35 | return m_average; 36 | } 37 | 38 | void reset() 39 | { 40 | m_average = T(0); 41 | m_values.clear(); 42 | } 43 | 44 | T average() const 45 | { 46 | return m_average; 47 | } 48 | 49 | operator T() const 50 | { 51 | return m_average; 52 | } 53 | 54 | private: 55 | T m_average = T(0); 56 | QQueue m_values; 57 | int m_limit; 58 | }; 59 | 60 | } // Utility 61 | } // Qt3DRaytrace 62 | --------------------------------------------------------------------------------